Compare commits
16 Commits
weblate-fi
...
fix/574
Author | SHA1 | Date | |
---|---|---|---|
861cf27af9
|
|||
952d768ab0
|
|||
2c91d2040e | |||
eff4435971 | |||
032fe99086 | |||
7add56df00 | |||
0ab05cece2 | |||
c63f6db61e | |||
56a68dfa91 | |||
157d131b37 | |||
3fae036db2 | |||
ce9d0934b6 | |||
a32e30374f
|
|||
cf46569f04
|
|||
022606c13c
|
|||
8cfda5229f
|
@ -1,6 +1,6 @@
|
||||
# integration test suite
|
||||
# export ABRA_DIR="$HOME/.abra_test"
|
||||
# export ABRA_TEST_DOMAIN=test.example.com
|
||||
# export TEST_SERVER=test.example.com
|
||||
# export ABRA_CI=1
|
||||
|
||||
# release automation
|
||||
|
@ -1,11 +1,12 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/leonelquinteros/gotext"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var AppCommand = &cobra.Command{
|
||||
Use: "app [cmd] [args] [flags]",
|
||||
Aliases: []string{"a"},
|
||||
Short: "Manage apps",
|
||||
Short: gotext.Get("Manage apps"),
|
||||
}
|
||||
|
@ -108,7 +108,11 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
||||
}
|
||||
|
||||
if err := lint.LintForErrors(app.Recipe); err != nil {
|
||||
log.Fatal(err)
|
||||
if internal.Chaos {
|
||||
log.Warn(err)
|
||||
} else {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateSecrets(cl, app); err != nil {
|
||||
|
@ -142,7 +142,7 @@ Use "--status/-S" flag to query all servers for the live deployment status.`,
|
||||
appStats.AutoUpdate = autoUpdate
|
||||
|
||||
var newUpdates []string
|
||||
if version != "unknown" && chaosVersion == "unknown" {
|
||||
if version != "unknown" && chaos == "false" {
|
||||
if err := app.Recipe.EnsureExists(); err != nil {
|
||||
log.Fatalf("unable to clone %s: %s", app.Name, err)
|
||||
}
|
||||
|
@ -233,6 +233,7 @@ var AppSecretRmCommand = &cobra.Command{
|
||||
Use: "remove <domain> [[secret] | --all] [flags]",
|
||||
Aliases: []string{"rm"},
|
||||
Short: "Remove a secret",
|
||||
Example: " abra app secret rm 1312.net oauth_key",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
|
@ -71,7 +71,7 @@ var AppVolumeListCommand = &cobra.Command{
|
||||
}
|
||||
|
||||
var AppVolumeRemoveCommand = &cobra.Command{
|
||||
Use: "remove <domain> [flags]",
|
||||
Use: "remove <domain> [volume] [flags]",
|
||||
Short: "Remove volume(s) associated with an app",
|
||||
Long: `Remove volumes associated with an app.
|
||||
|
||||
@ -83,6 +83,11 @@ you to make a seclection. Use the "?" key to see more help on navigating this
|
||||
interface.
|
||||
|
||||
Passing "--force/-f" will select all volumes for removal. Be careful.`,
|
||||
Example: ` # delete volumes interactively
|
||||
abra app volume rm 1312.net
|
||||
|
||||
# delete specific volume
|
||||
abra app volume rm 1312.net my_volume`,
|
||||
Aliases: []string{"rm"},
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
|
@ -32,12 +32,12 @@ func ValidateRecipe(args []string, cmdName string) recipe.Recipe {
|
||||
|
||||
localRecipes, err := recipe.GetRecipesLocal()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, recipeLocal := range localRecipes {
|
||||
if _, ok := knownRecipes[recipeLocal]; !ok {
|
||||
knownRecipes[recipeLocal] = true
|
||||
log.Debugf("can't read local recipes: %s", err)
|
||||
} else {
|
||||
for _, recipeLocal := range localRecipes {
|
||||
if _, ok := knownRecipes[recipeLocal]; !ok {
|
||||
knownRecipes[recipeLocal] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
111
go.mod
111
go.mod
@ -1,54 +1,59 @@
|
||||
module coopcloud.tech/abra
|
||||
|
||||
go 1.23.0
|
||||
go 1.23.5
|
||||
|
||||
toolchain go1.23.1
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb
|
||||
coopcloud.tech/tagcmp v0.0.0-20250427094623-9ea3bbbde8e5
|
||||
git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/charmbracelet/bubbletea v1.3.4
|
||||
github.com/charmbracelet/bubbletea v1.3.6
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
github.com/charmbracelet/log v0.4.1
|
||||
github.com/charmbracelet/log v0.4.2
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v28.0.1+incompatible
|
||||
github.com/docker/docker v28.0.1+incompatible
|
||||
github.com/docker/cli v28.3.3+incompatible
|
||||
github.com/docker/docker v28.3.3+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/go-git/go-git/v5 v5.14.0
|
||||
github.com/go-git/go-git/v5 v5.16.2
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/leonelquinteros/gotext v1.7.2
|
||||
github.com/moby/sys/signal v0.7.1
|
||||
github.com/moby/term v0.5.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/schollz/progressbar/v3 v3.18.0
|
||||
golang.org/x/term v0.30.0
|
||||
golang.org/x/term v0.34.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools/v3 v3.5.2
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.6 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
|
||||
github.com/charmbracelet/x/ansi v0.8.0 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.3.1 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.10.1 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/cloudflare/circl v1.6.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-connections v0.6.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
@ -59,13 +64,13 @@ require (
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
@ -82,8 +87,10 @@ require (
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/moby/sys/user v0.3.0 // indirect
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
@ -94,42 +101,42 @@ require (
|
||||
github.com/opencontainers/runc v1.1.13 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pjbgf/sha1cd v0.4.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.63.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/pflag v1.0.7 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||
google.golang.org/grpc v1.71.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250811191247-51f88131bc50 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
|
||||
google.golang.org/grpc v1.74.2 // indirect
|
||||
google.golang.org/protobuf v1.36.7 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
@ -142,15 +149,15 @@ require (
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/prometheus/client_golang v1.21.1 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||
github.com/sergi/go-diff v1.4.0 // indirect
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
golang.org/x/sys v0.31.0
|
||||
golang.org/x/sys v0.35.0
|
||||
)
|
||||
|
118
go.sum
118
go.sum
@ -24,13 +24,19 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb h1:Ws6WEwKXeaYEkfdkX6AqX1XLPuaCeyStEtxbmEJPllk=
|
||||
coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||
coopcloud.tech/tagcmp v0.0.0-20250427094623-9ea3bbbde8e5 h1:tphJCjFJw9fdjyKnbU0f7f3z5KtYE8VbUcAfu+oHKg8=
|
||||
coopcloud.tech/tagcmp v0.0.0-20250427094623-9ea3bbbde8e5/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
|
||||
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c h1:oeKnUB79PKYD8D0/unYuu7MRcWryQQWOns8+JL+acrs=
|
||||
git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c/go.mod h1:fQuhwrpg6qb9NlFXKYi/LysWu1wxjraS8sxyW12CUF0=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
@ -51,6 +57,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
@ -81,6 +89,8 @@ github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDe
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
@ -130,21 +140,32 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
|
||||
github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo=
|
||||
github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU=
|
||||
github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc=
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
|
||||
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
|
||||
github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
|
||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||
github.com/charmbracelet/log v0.4.1 h1:6AYnoHKADkghm/vt4neaNEXkxcXLSV2g1rdyFDOpTyk=
|
||||
github.com/charmbracelet/log v0.4.1/go.mod h1:pXgyTsqsVu4N9hGdHmQ0xEA4RsXof402LX9ZgiITn2I=
|
||||
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
|
||||
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
|
||||
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
|
||||
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
|
||||
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
|
||||
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
|
||||
@ -170,6 +191,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
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/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
@ -215,6 +238,10 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||
@ -237,6 +264,8 @@ github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.0/go.mod h1:/KsZXsJRllMbTKFfG0miFQWViQKdI9+9aSXs+HN0+ac=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
@ -285,6 +314,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
@ -314,6 +345,8 @@ github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyG
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs=
|
||||
github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
|
||||
github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
@ -322,6 +355,8 @@ github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
|
||||
github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
@ -330,6 +365,8 @@ github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
|
||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
@ -391,6 +428,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
|
||||
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
|
||||
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@ -406,6 +445,8 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
@ -424,6 +465,8 @@ github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
@ -528,9 +571,12 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@ -544,6 +590,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||
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 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
@ -611,6 +659,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leonelquinteros/gotext v1.7.2 h1:bDPndU8nt+/kRo1m4l/1OXiiy2v7Z7dfPQ9+YP7G1Mc=
|
||||
github.com/leonelquinteros/gotext v1.7.2/go.mod h1:9/haCkm5P7Jay1sxKDGJ5WIg4zkz8oZKw4ekNpALob8=
|
||||
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
@ -661,14 +711,20 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
|
||||
github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0=
|
||||
@ -676,6 +732,8 @@ github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5Xt
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
|
||||
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
@ -764,6 +822,8 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=
|
||||
github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -781,6 +841,8 @@ github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQ
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
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=
|
||||
@ -788,6 +850,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
@ -796,6 +860,8 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
@ -809,6 +875,8 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
@ -818,6 +886,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@ -830,6 +899,8 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
@ -870,6 +941,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
@ -948,27 +1021,47 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@ -995,6 +1088,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1007,6 +1102,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/exp v0.0.0-20250811191247-51f88131bc50 h1:3yiSh9fhy5/RhCSntf4Sy0Tnx50DmMpQ4MQdKKk4yg4=
|
||||
golang.org/x/exp v0.0.0-20250811191247-51f88131bc50/go.mod h1:rT6SFzZ7oxADUDx58pcaKFTcZ+inxAa9fTrYx/uVYwg=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -1072,6 +1169,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -1091,6 +1190,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -1172,11 +1273,15 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1188,6 +1293,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1196,6 +1303,8 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -1291,8 +1400,12 @@ google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7Fc
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a h1:DMCgtIAIQGZqJXMVzJF4MV8BlWoJh2ZuFiRdAleyr58=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a/go.mod h1:y2yVLIE/CSMCPXaHnSKXxu1spLPnglFLegmgdY23uuE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@ -1314,6 +1427,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
|
||||
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
|
||||
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=
|
||||
@ -1329,6 +1444,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
|
||||
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=
|
||||
@ -1368,6 +1485,7 @@ 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
|
12
locales/default.pot
Normal file
12
locales/default.pot
Normal file
@ -0,0 +1,12 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: \n"
|
||||
"X-Generator: xgotext\n"
|
||||
|
||||
#: app.go:11
|
||||
msgid "Manage apps"
|
||||
msgstr ""
|
20
locales/es/LC_MESSAGES/default.po
Normal file
20
locales/es/LC_MESSAGES/default.po
Normal file
@ -0,0 +1,20 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-08-04 14:15+0000\n"
|
||||
"PO-Revision-Date: 2025-08-04 14:15+0000\n"
|
||||
"Last-Translator: 3wordchant <3wc.coopcloud@doesthisthing.work>\n"
|
||||
"Language-Team: Spanish <https://translate.coopcloud.tech/projects/"
|
||||
"co-op-cloud/abra/es/>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.12.2\n"
|
||||
|
||||
#: app.go:11
|
||||
msgid "Manage apps"
|
||||
msgstr "Gestionar aplicaciones"
|
30
pkg/lang/lang.go
Normal file
30
pkg/lang/lang.go
Normal file
@ -0,0 +1,30 @@
|
||||
package lang
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetLocale() string {
|
||||
if loc := os.Getenv("LC_MESSAGES"); loc != "" {
|
||||
return NormalizeLocale(loc)
|
||||
}
|
||||
|
||||
if loc := os.Getenv("LANG"); loc != "" {
|
||||
return NormalizeLocale(loc)
|
||||
}
|
||||
|
||||
return "C.UTF-8"
|
||||
}
|
||||
|
||||
func NormalizeLocale(loc string) string {
|
||||
if idx := strings.Index(loc, "."); idx != -1 {
|
||||
return loc[:idx]
|
||||
}
|
||||
|
||||
if idx := strings.Index(loc, "@"); idx != -1 {
|
||||
return loc[:idx]
|
||||
}
|
||||
|
||||
return loc
|
||||
}
|
@ -184,6 +184,8 @@ var LintRules = map[string][]LintRule{
|
||||
func LintForErrors(recipe recipe.Recipe) error {
|
||||
log.Debugf("linting for critical errors in %s configs", recipe.Name)
|
||||
|
||||
var errors string
|
||||
|
||||
for level := range LintRules {
|
||||
if level != "error" {
|
||||
continue
|
||||
@ -196,14 +198,18 @@ func LintForErrors(recipe recipe.Recipe) error {
|
||||
|
||||
ok, err := rule.Function(recipe)
|
||||
if err != nil {
|
||||
return fmt.Errorf("lint %s: %s", rule.Ref, err)
|
||||
errors += fmt.Sprintf("\nlint %s: %s", rule.Ref, err)
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("lint error in %s configs: \"%s\" failed lint checks (%s)", recipe.Name, rule.Description, rule.Ref)
|
||||
errors += fmt.Sprintf("\n * %s (%s)", rule.Description, rule.Ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return fmt.Errorf("recipe '%s' failed lint checks:\n"+errors[1:], recipe.Name)
|
||||
}
|
||||
|
||||
log.Debugf("linting successful, %s is well configured", recipe.Name)
|
||||
|
||||
return nil
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/ui"
|
||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/stack/formatter"
|
||||
composetypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -426,7 +427,8 @@ func deployServices(
|
||||
services map[string]swarm.ServiceSpec,
|
||||
namespace convert.Namespace,
|
||||
sendAuth bool,
|
||||
resolveImage string) ([]ui.ServiceMeta, error) {
|
||||
resolveImage string,
|
||||
) ([]ui.ServiceMeta, error) {
|
||||
var servicesMeta []ui.ServiceMeta
|
||||
|
||||
existingServices, err := GetStackServices(ctx, cl, namespace.Name())
|
||||
@ -446,6 +448,21 @@ func deployServices(
|
||||
encodedAuth string
|
||||
)
|
||||
|
||||
// When sendAuth is set, use the docker cli to retrieve the auth token
|
||||
// for the image we are deploying.
|
||||
// This enables using a private registry by running docker login on the
|
||||
// machine, that abra is executed.
|
||||
if sendAuth {
|
||||
dockerCLI, err := command.NewDockerCli()
|
||||
if err != nil {
|
||||
log.Errorf("retrieving docker auth token: failed create docker cli: %s", err)
|
||||
}
|
||||
encodedAuth, err = command.RetrieveAuthTokenFromImage(dockerCLI.ConfigFile(), image)
|
||||
if err != nil {
|
||||
log.Errorf("failed to retrieve registry auth for image %s: %s", image, err)
|
||||
}
|
||||
}
|
||||
|
||||
if service, exists := existingServiceMap[name]; exists {
|
||||
log.Debugf("updating %s", name)
|
||||
|
||||
@ -587,7 +604,7 @@ func WaitOnServices(ctx context.Context, cl *dockerClient.Client, opts WaitOpts)
|
||||
fmt.Sprintf("%s_%s", opts.AppName, timestamp()),
|
||||
)
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(config.LOGS_DIR, opts.ServerName), 0764); err != nil {
|
||||
if err := os.MkdirAll(filepath.Join(config.LOGS_DIR, opts.ServerName), 0o764); err != nil {
|
||||
return fmt.Errorf("waitOnServices: error creating log dir: %s", err)
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,45 @@ teardown(){
|
||||
assert_success
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "bail if recipe lint errors and no --chaos" {
|
||||
# Break the recipe
|
||||
run sed -i '/traefik.enable=.*/d' "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml"
|
||||
assert_success
|
||||
|
||||
# Commit the breakage (so we can test without --chaos)
|
||||
_set_git_author
|
||||
|
||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" commit -a -m 'Break recipe'
|
||||
assert_success
|
||||
|
||||
# Make a broken release
|
||||
run $ABRA recipe sync --patch "$TEST_RECIPE"
|
||||
run $ABRA recipe release --patch -n "$TEST_RECIPE"
|
||||
|
||||
# Make sure we deploy latest
|
||||
_wipe_env_version
|
||||
|
||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input
|
||||
assert_failure
|
||||
assert_output --partial 'failed lint checks'
|
||||
|
||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" reset --hard HEAD~1
|
||||
latestRelease=$(_latest_release)
|
||||
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag -d "$latestRelease"
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "warn on recipe lint errors with --chaos" {
|
||||
# Break the recipe
|
||||
run sed -i '/traefik.enable=.*/d' "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml"
|
||||
assert_success
|
||||
|
||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks --chaos
|
||||
assert_success
|
||||
assert_output --partial 'failed lint checks'
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "ensure recipe up to date if no --offline" {
|
||||
wantHash=$(_get_n_hash 3)
|
||||
@ -147,16 +186,6 @@ teardown(){
|
||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE"
|
||||
}
|
||||
|
||||
@test "no deploy if lint error" {
|
||||
run sed -i '/traefik.enable=.*/d' "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml"
|
||||
assert_success
|
||||
|
||||
run $ABRA app deploy "$TEST_APP_DOMAIN" \
|
||||
--no-input --no-converge-checks --chaos
|
||||
assert_failure
|
||||
assert_output --partial 'failed lint checks'
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "error if already deployed and no --force/--chaos" {
|
||||
_deploy_app
|
||||
|
3
vendor/coopcloud.tech/tagcmp/renovate.json
vendored
3
vendor/coopcloud.tech/tagcmp/renovate.json
vendored
@ -1,3 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||
}
|
7
vendor/dario.cat/mergo/FUNDING.json
vendored
Normal file
7
vendor/dario.cat/mergo/FUNDING.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"drips": {
|
||||
"ethereum": {
|
||||
"ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930"
|
||||
}
|
||||
}
|
||||
}
|
5
vendor/dario.cat/mergo/README.md
vendored
5
vendor/dario.cat/mergo/README.md
vendored
@ -85,7 +85,6 @@ Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/depend
|
||||
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
|
||||
* [go-micro/go-micro](https://github.com/go-micro/go-micro)
|
||||
* [grafana/loki](https://github.com/grafana/loki)
|
||||
* [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
|
||||
* [masterminds/sprig](github.com/Masterminds/sprig)
|
||||
* [moby/moby](https://github.com/moby/moby)
|
||||
* [slackhq/nebula](https://github.com/slackhq/nebula)
|
||||
@ -191,10 +190,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note: if test are failing due missing package, please execute:
|
||||
|
||||
go get gopkg.in/yaml.v3
|
||||
|
||||
### Transformers
|
||||
|
||||
Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
|
||||
|
4
vendor/dario.cat/mergo/SECURITY.md
vendored
4
vendor/dario.cat/mergo/SECURITY.md
vendored
@ -4,8 +4,8 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.3.x | :white_check_mark: |
|
||||
| < 0.3 | :x: |
|
||||
| 1.x.x | :white_check_mark: |
|
||||
| < 1.0 | :x: |
|
||||
|
||||
## Security contact information
|
||||
|
||||
|
2
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
2
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
@ -3,7 +3,7 @@ reflection interface similar to Go's standard library `json` and `xml` packages.
|
||||
|
||||
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
|
||||
|
||||
Documentation: https://godocs.io/github.com/BurntSushi/toml
|
||||
Documentation: https://pkg.go.dev/github.com/BurntSushi/toml
|
||||
|
||||
See the [releases page](https://github.com/BurntSushi/toml/releases) for a
|
||||
changelog; this information is also in the git tag annotations (e.g. `git show
|
||||
|
33
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
33
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
@ -196,6 +196,19 @@ func (md *MetaData) PrimitiveDecode(primValue Primitive, v any) error {
|
||||
return md.unify(primValue.undecoded, rvalue(v))
|
||||
}
|
||||
|
||||
// markDecodedRecursive is a helper to mark any key under the given tmap as
|
||||
// decoded, recursing as needed
|
||||
func markDecodedRecursive(md *MetaData, tmap map[string]any) {
|
||||
for key := range tmap {
|
||||
md.decoded[md.context.add(key).String()] = struct{}{}
|
||||
if tmap, ok := tmap[key].(map[string]any); ok {
|
||||
md.context = append(md.context, key)
|
||||
markDecodedRecursive(md, tmap)
|
||||
md.context = md.context[0 : len(md.context)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unify performs a sort of type unification based on the structure of `rv`,
|
||||
// which is the client representation.
|
||||
//
|
||||
@ -222,6 +235,16 @@ func (md *MetaData) unify(data any, rv reflect.Value) error {
|
||||
if err != nil {
|
||||
return md.parseErr(err)
|
||||
}
|
||||
// Assume the Unmarshaler decoded everything, so mark all keys under
|
||||
// this table as decoded.
|
||||
if tmap, ok := data.(map[string]any); ok {
|
||||
markDecodedRecursive(md, tmap)
|
||||
}
|
||||
if aot, ok := data.([]map[string]any); ok {
|
||||
for _, tmap := range aot {
|
||||
markDecodedRecursive(md, tmap)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if v, ok := rvi.(encoding.TextUnmarshaler); ok {
|
||||
@ -540,12 +563,14 @@ func (md *MetaData) badtype(dst string, data any) error {
|
||||
|
||||
func (md *MetaData) parseErr(err error) error {
|
||||
k := md.context.String()
|
||||
d := string(md.data)
|
||||
return ParseError{
|
||||
LastKey: k,
|
||||
Position: md.keyInfo[k].pos,
|
||||
Line: md.keyInfo[k].pos.Line,
|
||||
Message: err.Error(),
|
||||
err: err,
|
||||
input: string(md.data),
|
||||
LastKey: k,
|
||||
Position: md.keyInfo[k].pos.withCol(d),
|
||||
Line: md.keyInfo[k].pos.Line,
|
||||
input: d,
|
||||
}
|
||||
}
|
||||
|
||||
|
46
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
46
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
@ -402,31 +402,30 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
||||
|
||||
// Sort keys so that we have deterministic output. And write keys directly
|
||||
// underneath this key first, before writing sub-structs or sub-maps.
|
||||
var mapKeysDirect, mapKeysSub []string
|
||||
var mapKeysDirect, mapKeysSub []reflect.Value
|
||||
for _, mapKey := range rv.MapKeys() {
|
||||
k := mapKey.String()
|
||||
if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {
|
||||
mapKeysSub = append(mapKeysSub, k)
|
||||
mapKeysSub = append(mapKeysSub, mapKey)
|
||||
} else {
|
||||
mapKeysDirect = append(mapKeysDirect, k)
|
||||
mapKeysDirect = append(mapKeysDirect, mapKey)
|
||||
}
|
||||
}
|
||||
|
||||
var writeMapKeys = func(mapKeys []string, trailC bool) {
|
||||
sort.Strings(mapKeys)
|
||||
writeMapKeys := func(mapKeys []reflect.Value, trailC bool) {
|
||||
sort.Slice(mapKeys, func(i, j int) bool { return mapKeys[i].String() < mapKeys[j].String() })
|
||||
for i, mapKey := range mapKeys {
|
||||
val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey)))
|
||||
val := eindirect(rv.MapIndex(mapKey))
|
||||
if isNil(val) {
|
||||
continue
|
||||
}
|
||||
|
||||
if inline {
|
||||
enc.writeKeyValue(Key{mapKey}, val, true)
|
||||
enc.writeKeyValue(Key{mapKey.String()}, val, true)
|
||||
if trailC || i != len(mapKeys)-1 {
|
||||
enc.wf(", ")
|
||||
}
|
||||
} else {
|
||||
enc.encode(key.add(mapKey), val)
|
||||
enc.encode(key.add(mapKey.String()), val)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,8 +440,6 @@ func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
|
||||
}
|
||||
}
|
||||
|
||||
const is32Bit = (32 << (^uint(0) >> 63)) == 32
|
||||
|
||||
func pointerTo(t reflect.Type) reflect.Type {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
return pointerTo(t.Elem())
|
||||
@ -477,15 +474,14 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
||||
|
||||
frv := eindirect(rv.Field(i))
|
||||
|
||||
if is32Bit {
|
||||
// Copy so it works correct on 32bit archs; not clear why this
|
||||
// is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4
|
||||
// This also works fine on 64bit, but 32bit archs are somewhat
|
||||
// rare and this is a wee bit faster.
|
||||
copyStart := make([]int, len(start))
|
||||
copy(copyStart, start)
|
||||
start = copyStart
|
||||
}
|
||||
// Need to make a copy because ... ehm, I don't know why... I guess
|
||||
// allocating a new array can cause it to fail(?)
|
||||
//
|
||||
// Done for: https://github.com/BurntSushi/toml/issues/430
|
||||
// Previously only on 32bit for: https://github.com/BurntSushi/toml/issues/314
|
||||
copyStart := make([]int, len(start))
|
||||
copy(copyStart, start)
|
||||
start = copyStart
|
||||
|
||||
// Treat anonymous struct fields with tag names as though they are
|
||||
// not anonymous, like encoding/json does.
|
||||
@ -507,7 +503,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
||||
}
|
||||
addFields(rt, rv, nil)
|
||||
|
||||
writeFields := func(fields [][]int) {
|
||||
writeFields := func(fields [][]int, totalFields int) {
|
||||
for _, fieldIndex := range fields {
|
||||
fieldType := rt.FieldByIndex(fieldIndex)
|
||||
fieldVal := rv.FieldByIndex(fieldIndex)
|
||||
@ -537,7 +533,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
||||
|
||||
if inline {
|
||||
enc.writeKeyValue(Key{keyName}, fieldVal, true)
|
||||
if fieldIndex[0] != len(fields)-1 {
|
||||
if fieldIndex[0] != totalFields-1 {
|
||||
enc.wf(", ")
|
||||
}
|
||||
} else {
|
||||
@ -549,8 +545,10 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
|
||||
if inline {
|
||||
enc.wf("{")
|
||||
}
|
||||
writeFields(fieldsDirect)
|
||||
writeFields(fieldsSub)
|
||||
|
||||
l := len(fieldsDirect) + len(fieldsSub)
|
||||
writeFields(fieldsDirect, l)
|
||||
writeFields(fieldsSub, l)
|
||||
if inline {
|
||||
enc.wf("}")
|
||||
}
|
||||
|
69
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
69
vendor/github.com/BurntSushi/toml/error.go
generated
vendored
@ -67,21 +67,36 @@ type ParseError struct {
|
||||
// Position of an error.
|
||||
type Position struct {
|
||||
Line int // Line number, starting at 1.
|
||||
Col int // Error column, starting at 1.
|
||||
Start int // Start of error, as byte offset starting at 0.
|
||||
Len int // Lenght in bytes.
|
||||
Len int // Length of the error in bytes.
|
||||
}
|
||||
|
||||
func (p Position) withCol(tomlFile string) Position {
|
||||
var (
|
||||
pos int
|
||||
lines = strings.Split(tomlFile, "\n")
|
||||
)
|
||||
for i := range lines {
|
||||
ll := len(lines[i]) + 1 // +1 for the removed newline
|
||||
if pos+ll >= p.Start {
|
||||
p.Col = p.Start - pos + 1
|
||||
if p.Col < 1 { // Should never happen, but just in case.
|
||||
p.Col = 1
|
||||
}
|
||||
break
|
||||
}
|
||||
pos += ll
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (pe ParseError) Error() string {
|
||||
msg := pe.Message
|
||||
if msg == "" { // Error from errorf()
|
||||
msg = pe.err.Error()
|
||||
}
|
||||
|
||||
if pe.LastKey == "" {
|
||||
return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, msg)
|
||||
return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, pe.Message)
|
||||
}
|
||||
return fmt.Sprintf("toml: line %d (last key %q): %s",
|
||||
pe.Position.Line, pe.LastKey, msg)
|
||||
pe.Position.Line, pe.LastKey, pe.Message)
|
||||
}
|
||||
|
||||
// ErrorWithPosition returns the error with detailed location context.
|
||||
@ -92,26 +107,19 @@ func (pe ParseError) ErrorWithPosition() string {
|
||||
return pe.Error()
|
||||
}
|
||||
|
||||
var (
|
||||
lines = strings.Split(pe.input, "\n")
|
||||
col = pe.column(lines)
|
||||
b = new(strings.Builder)
|
||||
)
|
||||
|
||||
msg := pe.Message
|
||||
if msg == "" {
|
||||
msg = pe.err.Error()
|
||||
}
|
||||
|
||||
// TODO: don't show control characters as literals? This may not show up
|
||||
// well everywhere.
|
||||
|
||||
var (
|
||||
lines = strings.Split(pe.input, "\n")
|
||||
b = new(strings.Builder)
|
||||
)
|
||||
if pe.Position.Len == 1 {
|
||||
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n",
|
||||
msg, pe.Position.Line, col+1)
|
||||
pe.Message, pe.Position.Line, pe.Position.Col)
|
||||
} else {
|
||||
fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n",
|
||||
msg, pe.Position.Line, col, col+pe.Position.Len)
|
||||
pe.Message, pe.Position.Line, pe.Position.Col, pe.Position.Col+pe.Position.Len-1)
|
||||
}
|
||||
if pe.Position.Line > 2 {
|
||||
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, expandTab(lines[pe.Position.Line-3]))
|
||||
@ -129,7 +137,7 @@ func (pe ParseError) ErrorWithPosition() string {
|
||||
diff := len(expanded) - len(lines[pe.Position.Line-1])
|
||||
|
||||
fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, expanded)
|
||||
fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", col+diff), strings.Repeat("^", pe.Position.Len))
|
||||
fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", pe.Position.Col-1+diff), strings.Repeat("^", pe.Position.Len))
|
||||
return b.String()
|
||||
}
|
||||
|
||||
@ -151,23 +159,6 @@ func (pe ParseError) ErrorWithUsage() string {
|
||||
return m
|
||||
}
|
||||
|
||||
func (pe ParseError) column(lines []string) int {
|
||||
var pos, col int
|
||||
for i := range lines {
|
||||
ll := len(lines[i]) + 1 // +1 for the removed newline
|
||||
if pos+ll >= pe.Position.Start {
|
||||
col = pe.Position.Start - pos
|
||||
if col < 0 { // Should never happen, but just in case.
|
||||
col = 0
|
||||
}
|
||||
break
|
||||
}
|
||||
pos += ll
|
||||
}
|
||||
|
||||
return col
|
||||
}
|
||||
|
||||
func expandTab(s string) string {
|
||||
var (
|
||||
b strings.Builder
|
||||
|
33
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
33
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
@ -275,7 +275,9 @@ func (lx *lexer) errorPos(start, length int, err error) stateFn {
|
||||
func (lx *lexer) errorf(format string, values ...any) stateFn {
|
||||
if lx.atEOF {
|
||||
pos := lx.getPos()
|
||||
pos.Line--
|
||||
if lx.pos >= 1 && lx.input[lx.pos-1] == '\n' {
|
||||
pos.Line--
|
||||
}
|
||||
pos.Len = 1
|
||||
pos.Start = lx.pos - 1
|
||||
lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}
|
||||
@ -492,6 +494,9 @@ func lexKeyEnd(lx *lexer) stateFn {
|
||||
lx.emit(itemKeyEnd)
|
||||
return lexSkip(lx, lexValue)
|
||||
default:
|
||||
if r == '\n' {
|
||||
return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r))
|
||||
}
|
||||
return lx.errorf("expected '.' or '=', but got %q instead", r)
|
||||
}
|
||||
}
|
||||
@ -560,6 +565,9 @@ func lexValue(lx *lexer) stateFn {
|
||||
if r == eof {
|
||||
return lx.errorf("unexpected EOF; expected value")
|
||||
}
|
||||
if r == '\n' {
|
||||
return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r))
|
||||
}
|
||||
return lx.errorf("expected value but found %q instead", r)
|
||||
}
|
||||
|
||||
@ -1111,7 +1119,7 @@ func lexBaseNumberOrDate(lx *lexer) stateFn {
|
||||
case 'x':
|
||||
r = lx.peek()
|
||||
if !isHex(r) {
|
||||
lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r)
|
||||
lx.errorf("not a hexadecimal number: '%s%c'", lx.current(), r)
|
||||
}
|
||||
return lexHexInteger
|
||||
}
|
||||
@ -1259,23 +1267,6 @@ func isBinary(r rune) bool { return r == '0' || r == '1' }
|
||||
func isOctal(r rune) bool { return r >= '0' && r <= '7' }
|
||||
func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') }
|
||||
func isBareKeyChar(r rune, tomlNext bool) bool {
|
||||
if tomlNext {
|
||||
return (r >= 'A' && r <= 'Z') ||
|
||||
(r >= 'a' && r <= 'z') ||
|
||||
(r >= '0' && r <= '9') ||
|
||||
r == '_' || r == '-' ||
|
||||
r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) ||
|
||||
(r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) ||
|
||||
(r >= 0x037f && r <= 0x1fff) ||
|
||||
(r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) ||
|
||||
(r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) ||
|
||||
(r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) ||
|
||||
(r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) ||
|
||||
(r >= 0x10000 && r <= 0xeffff)
|
||||
}
|
||||
|
||||
return (r >= 'A' && r <= 'Z') ||
|
||||
(r >= 'a' && r <= 'z') ||
|
||||
(r >= '0' && r <= '9') ||
|
||||
r == '_' || r == '-'
|
||||
return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') ||
|
||||
(r >= '0' && r <= '9') || r == '_' || r == '-'
|
||||
}
|
||||
|
3
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
3
vendor/github.com/BurntSushi/toml/meta.go
generated
vendored
@ -135,9 +135,6 @@ func (k Key) maybeQuoted(i int) string {
|
||||
|
||||
// Like append(), but only increase the cap by 1.
|
||||
func (k Key) add(piece string) Key {
|
||||
if cap(k) > len(k) {
|
||||
return append(k, piece)
|
||||
}
|
||||
newKey := make(Key, len(k)+1)
|
||||
copy(newKey, k)
|
||||
newKey[len(k)] = piece
|
||||
|
17
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
17
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
@ -50,7 +50,6 @@ func parse(data string) (p *parser, err error) {
|
||||
// it anyway.
|
||||
if strings.HasPrefix(data, "\xff\xfe") || strings.HasPrefix(data, "\xfe\xff") { // UTF-16
|
||||
data = data[2:]
|
||||
//lint:ignore S1017 https://github.com/dominikh/go-tools/issues/1447
|
||||
} else if strings.HasPrefix(data, "\xef\xbb\xbf") { // UTF-8
|
||||
data = data[3:]
|
||||
}
|
||||
@ -65,7 +64,7 @@ func parse(data string) (p *parser, err error) {
|
||||
if i := strings.IndexRune(data[:ex], 0); i > -1 {
|
||||
return nil, ParseError{
|
||||
Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8",
|
||||
Position: Position{Line: 1, Start: i, Len: 1},
|
||||
Position: Position{Line: 1, Col: 1, Start: i, Len: 1},
|
||||
Line: 1,
|
||||
input: data,
|
||||
}
|
||||
@ -92,8 +91,9 @@ func parse(data string) (p *parser, err error) {
|
||||
|
||||
func (p *parser) panicErr(it item, err error) {
|
||||
panic(ParseError{
|
||||
Message: err.Error(),
|
||||
err: err,
|
||||
Position: it.pos,
|
||||
Position: it.pos.withCol(p.lx.input),
|
||||
Line: it.pos.Len,
|
||||
LastKey: p.current(),
|
||||
})
|
||||
@ -102,7 +102,7 @@ func (p *parser) panicErr(it item, err error) {
|
||||
func (p *parser) panicItemf(it item, format string, v ...any) {
|
||||
panic(ParseError{
|
||||
Message: fmt.Sprintf(format, v...),
|
||||
Position: it.pos,
|
||||
Position: it.pos.withCol(p.lx.input),
|
||||
Line: it.pos.Len,
|
||||
LastKey: p.current(),
|
||||
})
|
||||
@ -111,7 +111,7 @@ func (p *parser) panicItemf(it item, format string, v ...any) {
|
||||
func (p *parser) panicf(format string, v ...any) {
|
||||
panic(ParseError{
|
||||
Message: fmt.Sprintf(format, v...),
|
||||
Position: p.pos,
|
||||
Position: p.pos.withCol(p.lx.input),
|
||||
Line: p.pos.Line,
|
||||
LastKey: p.current(),
|
||||
})
|
||||
@ -123,10 +123,11 @@ func (p *parser) next() item {
|
||||
if it.typ == itemError {
|
||||
if it.err != nil {
|
||||
panic(ParseError{
|
||||
Position: it.pos,
|
||||
Message: it.err.Error(),
|
||||
err: it.err,
|
||||
Position: it.pos.withCol(p.lx.input),
|
||||
Line: it.pos.Line,
|
||||
LastKey: p.current(),
|
||||
err: it.err,
|
||||
})
|
||||
}
|
||||
|
||||
@ -527,7 +528,7 @@ func numUnderscoresOK(s string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// isHexis a superset of all the permissable characters surrounding an
|
||||
// isHex is a superset of all the permissible characters surrounding an
|
||||
// underscore.
|
||||
accept = isHex(r)
|
||||
}
|
||||
|
10
vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
generated
vendored
10
vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
generated
vendored
@ -180,6 +180,16 @@ func (dke ErrMalformedMessage) Error() string {
|
||||
return "openpgp: malformed message " + string(dke)
|
||||
}
|
||||
|
||||
type messageTooLargeError int
|
||||
|
||||
func (e messageTooLargeError) Error() string {
|
||||
return "openpgp: decompressed message size exceeds provided limit"
|
||||
}
|
||||
|
||||
// ErrMessageTooLarge is returned if the read data from
|
||||
// a compressed packet exceeds the provided limit.
|
||||
var ErrMessageTooLarge error = messageTooLargeError(0)
|
||||
|
||||
// ErrEncryptionKeySelection is returned if encryption key selection fails (v2 API).
|
||||
type ErrEncryptionKeySelection struct {
|
||||
PrimaryKeyId string
|
||||
|
6
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
generated
vendored
6
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
generated
vendored
@ -37,7 +37,7 @@ func (conf *AEADConfig) Mode() AEADMode {
|
||||
|
||||
// ChunkSizeByte returns the byte indicating the chunk size. The effective
|
||||
// chunk size is computed with the formula uint64(1) << (chunkSizeByte + 6)
|
||||
// limit to 16 = 4 MiB
|
||||
// limit chunkSizeByte to 16 which equals to 2^22 = 4 MiB
|
||||
// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
|
||||
func (conf *AEADConfig) ChunkSizeByte() byte {
|
||||
if conf == nil || conf.ChunkSize == 0 {
|
||||
@ -49,8 +49,8 @@ func (conf *AEADConfig) ChunkSizeByte() byte {
|
||||
switch {
|
||||
case exponent < 6:
|
||||
exponent = 6
|
||||
case exponent > 16:
|
||||
exponent = 16
|
||||
case exponent > 22:
|
||||
exponent = 22
|
||||
}
|
||||
|
||||
return byte(exponent - 6)
|
||||
|
31
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
generated
vendored
31
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
generated
vendored
@ -98,6 +98,16 @@ func (c *Compressed) parse(r io.Reader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// LimitedBodyReader wraps the provided body reader with a limiter that restricts
|
||||
// the number of bytes read to the specified limit.
|
||||
// If limit is nil, the reader is unbounded.
|
||||
func (c *Compressed) LimitedBodyReader(limit *int64) io.Reader {
|
||||
if limit == nil {
|
||||
return c.Body
|
||||
}
|
||||
return &LimitReader{R: c.Body, N: *limit}
|
||||
}
|
||||
|
||||
// compressedWriterCloser represents the serialized compression stream
|
||||
// header and the compressor. Its Close() method ensures that both the
|
||||
// compressor and serialized stream header are closed. Its Write()
|
||||
@ -159,3 +169,24 @@ func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *Compression
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// LimitReader is an io.Reader that fails with MessageToLarge if read bytes exceed N.
|
||||
type LimitReader struct {
|
||||
R io.Reader // underlying reader
|
||||
N int64 // max bytes allowed
|
||||
}
|
||||
|
||||
func (l *LimitReader) Read(p []byte) (int, error) {
|
||||
if l.N <= 0 {
|
||||
return 0, errors.ErrMessageTooLarge
|
||||
}
|
||||
|
||||
n, err := l.R.Read(p)
|
||||
l.N -= int64(n)
|
||||
|
||||
if err == nil && l.N <= 0 {
|
||||
err = errors.ErrMessageTooLarge
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
12
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
generated
vendored
12
vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
generated
vendored
@ -178,6 +178,11 @@ type Config struct {
|
||||
// When set to true, a key without flags is treated as if all flags are enabled.
|
||||
// This behavior is consistent with GPG.
|
||||
InsecureAllowAllKeyFlagsWhenMissing bool
|
||||
|
||||
// MaxDecompressedMessageSize specifies the maximum number of bytes that can be
|
||||
// read from a compressed packet. This serves as an upper limit to prevent
|
||||
// excessively large decompressed messages.
|
||||
MaxDecompressedMessageSize *int64
|
||||
}
|
||||
|
||||
func (c *Config) Random() io.Reader {
|
||||
@ -415,6 +420,13 @@ func (c *Config) AllowAllKeyFlagsWhenMissing() bool {
|
||||
return c.InsecureAllowAllKeyFlagsWhenMissing
|
||||
}
|
||||
|
||||
func (c *Config) DecompressedMessageSizeLimit() *int64 {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.MaxDecompressedMessageSize
|
||||
}
|
||||
|
||||
// BoolPointer is a helper function to set a boolean pointer in the Config.
|
||||
// e.g., config.CheckPacketSequence = BoolPointer(true)
|
||||
func BoolPointer(value bool) *bool {
|
||||
|
2
vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
generated
vendored
2
vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
generated
vendored
@ -259,7 +259,7 @@ FindLiteralData:
|
||||
}
|
||||
switch p := p.(type) {
|
||||
case *packet.Compressed:
|
||||
if err := packets.Push(p.Body); err != nil {
|
||||
if err := packets.Push(p.LimitedBodyReader(config.DecompressedMessageSizeLimit())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *packet.OnePassSignature:
|
||||
|
124
vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
generated
vendored
124
vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
generated
vendored
@ -253,34 +253,12 @@ func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entit
|
||||
}
|
||||
|
||||
var hash crypto.Hash
|
||||
for _, hashId := range candidateHashes {
|
||||
if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
|
||||
hash = h
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the hash specified by config is a candidate, we'll use that.
|
||||
if configuredHash := config.Hash(); configuredHash.Available() {
|
||||
for _, hashId := range candidateHashes {
|
||||
if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
|
||||
hash = h
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hash == 0 {
|
||||
hashId := candidateHashes[0]
|
||||
name, ok := algorithm.HashIdToString(hashId)
|
||||
if !ok {
|
||||
name = "#" + strconv.Itoa(int(hashId))
|
||||
}
|
||||
return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
|
||||
}
|
||||
|
||||
var salt []byte
|
||||
if signer != nil {
|
||||
if hash, err = selectHash(candidateHashes, config.Hash(), signer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var opsVersion = 3
|
||||
if signer.Version == 6 {
|
||||
opsVersion = signer.Version
|
||||
@ -558,13 +536,34 @@ func (s signatureWriter) Close() error {
|
||||
return s.encryptedData.Close()
|
||||
}
|
||||
|
||||
func selectHashForSigningKey(config *packet.Config, signer *packet.PublicKey) crypto.Hash {
|
||||
acceptableHashes := acceptableHashesToWrite(signer)
|
||||
hash, ok := algorithm.HashToHashId(config.Hash())
|
||||
if !ok {
|
||||
return config.Hash()
|
||||
}
|
||||
for _, acceptableHashes := range acceptableHashes {
|
||||
if acceptableHashes == hash {
|
||||
return config.Hash()
|
||||
}
|
||||
}
|
||||
if len(acceptableHashes) > 0 {
|
||||
defaultAcceptedHash, ok := algorithm.HashIdToHash(acceptableHashes[0])
|
||||
if ok {
|
||||
return defaultAcceptedHash
|
||||
}
|
||||
}
|
||||
return config.Hash()
|
||||
}
|
||||
|
||||
func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature {
|
||||
sigLifetimeSecs := config.SigLifetime()
|
||||
hash := selectHashForSigningKey(config, signer)
|
||||
return &packet.Signature{
|
||||
Version: signer.Version,
|
||||
SigType: sigType,
|
||||
PubKeyAlgo: signer.PubKeyAlgo,
|
||||
Hash: config.Hash(),
|
||||
Hash: hash,
|
||||
CreationTime: config.Now(),
|
||||
IssuerKeyId: &signer.KeyId,
|
||||
IssuerFingerprint: signer.Fingerprint,
|
||||
@ -618,3 +617,74 @@ func handleCompression(compressed io.WriteCloser, candidateCompression []uint8,
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// selectHash selects the preferred hash given the candidateHashes and the configuredHash
|
||||
func selectHash(candidateHashes []byte, configuredHash crypto.Hash, signer *packet.PrivateKey) (hash crypto.Hash, err error) {
|
||||
acceptableHashes := acceptableHashesToWrite(&signer.PublicKey)
|
||||
candidateHashes = intersectPreferences(acceptableHashes, candidateHashes)
|
||||
|
||||
for _, hashId := range candidateHashes {
|
||||
if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
|
||||
hash = h
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the hash specified by config is a candidate, we'll use that.
|
||||
if configuredHash.Available() {
|
||||
for _, hashId := range candidateHashes {
|
||||
if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
|
||||
hash = h
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hash == 0 {
|
||||
if len(acceptableHashes) > 0 {
|
||||
if h, ok := algorithm.HashIdToHash(acceptableHashes[0]); ok {
|
||||
hash = h
|
||||
} else {
|
||||
return 0, errors.UnsupportedError("no candidate hash functions are compiled in.")
|
||||
}
|
||||
} else {
|
||||
return 0, errors.UnsupportedError("no candidate hash functions are compiled in.")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func acceptableHashesToWrite(singingKey *packet.PublicKey) []uint8 {
|
||||
switch singingKey.PubKeyAlgo {
|
||||
case packet.PubKeyAlgoEd448:
|
||||
return []uint8{
|
||||
hashToHashId(crypto.SHA512),
|
||||
hashToHashId(crypto.SHA3_512),
|
||||
}
|
||||
case packet.PubKeyAlgoECDSA, packet.PubKeyAlgoEdDSA:
|
||||
if curve, err := singingKey.Curve(); err == nil {
|
||||
if curve == packet.Curve448 ||
|
||||
curve == packet.CurveNistP521 ||
|
||||
curve == packet.CurveBrainpoolP512 {
|
||||
return []uint8{
|
||||
hashToHashId(crypto.SHA512),
|
||||
hashToHashId(crypto.SHA3_512),
|
||||
}
|
||||
} else if curve == packet.CurveBrainpoolP384 ||
|
||||
curve == packet.CurveNistP384 {
|
||||
return []uint8{
|
||||
hashToHashId(crypto.SHA384),
|
||||
hashToHashId(crypto.SHA512),
|
||||
hashToHashId(crypto.SHA3_512),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return []uint8{
|
||||
hashToHashId(crypto.SHA256),
|
||||
hashToHashId(crypto.SHA384),
|
||||
hashToHashId(crypto.SHA512),
|
||||
hashToHashId(crypto.SHA3_256),
|
||||
hashToHashId(crypto.SHA3_512),
|
||||
}
|
||||
}
|
||||
|
62
vendor/github.com/cenkalti/backoff/v4/context.go
generated
vendored
62
vendor/github.com/cenkalti/backoff/v4/context.go
generated
vendored
@ -1,62 +0,0 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BackOffContext is a backoff policy that stops retrying after the context
|
||||
// is canceled.
|
||||
type BackOffContext interface { // nolint: golint
|
||||
BackOff
|
||||
Context() context.Context
|
||||
}
|
||||
|
||||
type backOffContext struct {
|
||||
BackOff
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// WithContext returns a BackOffContext with context ctx
|
||||
//
|
||||
// ctx must not be nil
|
||||
func WithContext(b BackOff, ctx context.Context) BackOffContext { // nolint: golint
|
||||
if ctx == nil {
|
||||
panic("nil context")
|
||||
}
|
||||
|
||||
if b, ok := b.(*backOffContext); ok {
|
||||
return &backOffContext{
|
||||
BackOff: b.BackOff,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
return &backOffContext{
|
||||
BackOff: b,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func getContext(b BackOff) context.Context {
|
||||
if cb, ok := b.(BackOffContext); ok {
|
||||
return cb.Context()
|
||||
}
|
||||
if tb, ok := b.(*backOffTries); ok {
|
||||
return getContext(tb.delegate)
|
||||
}
|
||||
return context.Background()
|
||||
}
|
||||
|
||||
func (b *backOffContext) Context() context.Context {
|
||||
return b.ctx
|
||||
}
|
||||
|
||||
func (b *backOffContext) NextBackOff() time.Duration {
|
||||
select {
|
||||
case <-b.ctx.Done():
|
||||
return Stop
|
||||
default:
|
||||
return b.BackOff.NextBackOff()
|
||||
}
|
||||
}
|
216
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
216
vendor/github.com/cenkalti/backoff/v4/exponential.go
generated
vendored
@ -1,216 +0,0 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
ExponentialBackOff is a backoff implementation that increases the backoff
|
||||
period for each retry attempt using a randomization function that grows exponentially.
|
||||
|
||||
NextBackOff() is calculated using the following formula:
|
||||
|
||||
randomized interval =
|
||||
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
||||
|
||||
In other words NextBackOff() will range between the randomization factor
|
||||
percentage below and above the retry interval.
|
||||
|
||||
For example, given the following parameters:
|
||||
|
||||
RetryInterval = 2
|
||||
RandomizationFactor = 0.5
|
||||
Multiplier = 2
|
||||
|
||||
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
|
||||
multiplied by the exponential, that is, between 2 and 6 seconds.
|
||||
|
||||
Note: MaxInterval caps the RetryInterval and not the randomized interval.
|
||||
|
||||
If the time elapsed since an ExponentialBackOff instance is created goes past the
|
||||
MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop.
|
||||
|
||||
The elapsed time can be reset by calling Reset().
|
||||
|
||||
Example: Given the following default arguments, for 10 tries the sequence will be,
|
||||
and assuming we go over the MaxElapsedTime on the 10th try:
|
||||
|
||||
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
||||
|
||||
1 0.5 [0.25, 0.75]
|
||||
2 0.75 [0.375, 1.125]
|
||||
3 1.125 [0.562, 1.687]
|
||||
4 1.687 [0.8435, 2.53]
|
||||
5 2.53 [1.265, 3.795]
|
||||
6 3.795 [1.897, 5.692]
|
||||
7 5.692 [2.846, 8.538]
|
||||
8 8.538 [4.269, 12.807]
|
||||
9 12.807 [6.403, 19.210]
|
||||
10 19.210 backoff.Stop
|
||||
|
||||
Note: Implementation is not thread-safe.
|
||||
*/
|
||||
type ExponentialBackOff struct {
|
||||
InitialInterval time.Duration
|
||||
RandomizationFactor float64
|
||||
Multiplier float64
|
||||
MaxInterval time.Duration
|
||||
// After MaxElapsedTime the ExponentialBackOff returns Stop.
|
||||
// It never stops if MaxElapsedTime == 0.
|
||||
MaxElapsedTime time.Duration
|
||||
Stop time.Duration
|
||||
Clock Clock
|
||||
|
||||
currentInterval time.Duration
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
// Clock is an interface that returns current time for BackOff.
|
||||
type Clock interface {
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
// ExponentialBackOffOpts is a function type used to configure ExponentialBackOff options.
|
||||
type ExponentialBackOffOpts func(*ExponentialBackOff)
|
||||
|
||||
// Default values for ExponentialBackOff.
|
||||
const (
|
||||
DefaultInitialInterval = 500 * time.Millisecond
|
||||
DefaultRandomizationFactor = 0.5
|
||||
DefaultMultiplier = 1.5
|
||||
DefaultMaxInterval = 60 * time.Second
|
||||
DefaultMaxElapsedTime = 15 * time.Minute
|
||||
)
|
||||
|
||||
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
||||
func NewExponentialBackOff(opts ...ExponentialBackOffOpts) *ExponentialBackOff {
|
||||
b := &ExponentialBackOff{
|
||||
InitialInterval: DefaultInitialInterval,
|
||||
RandomizationFactor: DefaultRandomizationFactor,
|
||||
Multiplier: DefaultMultiplier,
|
||||
MaxInterval: DefaultMaxInterval,
|
||||
MaxElapsedTime: DefaultMaxElapsedTime,
|
||||
Stop: Stop,
|
||||
Clock: SystemClock,
|
||||
}
|
||||
for _, fn := range opts {
|
||||
fn(b)
|
||||
}
|
||||
b.Reset()
|
||||
return b
|
||||
}
|
||||
|
||||
// WithInitialInterval sets the initial interval between retries.
|
||||
func WithInitialInterval(duration time.Duration) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.InitialInterval = duration
|
||||
}
|
||||
}
|
||||
|
||||
// WithRandomizationFactor sets the randomization factor to add jitter to intervals.
|
||||
func WithRandomizationFactor(randomizationFactor float64) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.RandomizationFactor = randomizationFactor
|
||||
}
|
||||
}
|
||||
|
||||
// WithMultiplier sets the multiplier for increasing the interval after each retry.
|
||||
func WithMultiplier(multiplier float64) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.Multiplier = multiplier
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxInterval sets the maximum interval between retries.
|
||||
func WithMaxInterval(duration time.Duration) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.MaxInterval = duration
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxElapsedTime sets the maximum total time for retries.
|
||||
func WithMaxElapsedTime(duration time.Duration) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.MaxElapsedTime = duration
|
||||
}
|
||||
}
|
||||
|
||||
// WithRetryStopDuration sets the duration after which retries should stop.
|
||||
func WithRetryStopDuration(duration time.Duration) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.Stop = duration
|
||||
}
|
||||
}
|
||||
|
||||
// WithClockProvider sets the clock used to measure time.
|
||||
func WithClockProvider(clock Clock) ExponentialBackOffOpts {
|
||||
return func(ebo *ExponentialBackOff) {
|
||||
ebo.Clock = clock
|
||||
}
|
||||
}
|
||||
|
||||
type systemClock struct{}
|
||||
|
||||
func (t systemClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// SystemClock implements Clock interface that uses time.Now().
|
||||
var SystemClock = systemClock{}
|
||||
|
||||
// Reset the interval back to the initial retry interval and restarts the timer.
|
||||
// Reset must be called before using b.
|
||||
func (b *ExponentialBackOff) Reset() {
|
||||
b.currentInterval = b.InitialInterval
|
||||
b.startTime = b.Clock.Now()
|
||||
}
|
||||
|
||||
// NextBackOff calculates the next backoff interval using the formula:
|
||||
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
||||
func (b *ExponentialBackOff) NextBackOff() time.Duration {
|
||||
// Make sure we have not gone over the maximum elapsed time.
|
||||
elapsed := b.GetElapsedTime()
|
||||
next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
|
||||
b.incrementCurrentInterval()
|
||||
if b.MaxElapsedTime != 0 && elapsed+next > b.MaxElapsedTime {
|
||||
return b.Stop
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
|
||||
// is created and is reset when Reset() is called.
|
||||
//
|
||||
// The elapsed time is computed using time.Now().UnixNano(). It is
|
||||
// safe to call even while the backoff policy is used by a running
|
||||
// ticker.
|
||||
func (b *ExponentialBackOff) GetElapsedTime() time.Duration {
|
||||
return b.Clock.Now().Sub(b.startTime)
|
||||
}
|
||||
|
||||
// Increments the current interval by multiplying it with the multiplier.
|
||||
func (b *ExponentialBackOff) incrementCurrentInterval() {
|
||||
// Check for overflow, if overflow is detected set the current interval to the max interval.
|
||||
if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier {
|
||||
b.currentInterval = b.MaxInterval
|
||||
} else {
|
||||
b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a random value from the following interval:
|
||||
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
||||
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
|
||||
if randomizationFactor == 0 {
|
||||
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
|
||||
}
|
||||
var delta = randomizationFactor * float64(currentInterval)
|
||||
var minInterval = float64(currentInterval) - delta
|
||||
var maxInterval = float64(currentInterval) + delta
|
||||
|
||||
// Get a random value from the range [minInterval, maxInterval].
|
||||
// The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then
|
||||
// we want a 33% chance for selecting either 1, 2 or 3.
|
||||
return time.Duration(minInterval + (random * (maxInterval - minInterval + 1)))
|
||||
}
|
146
vendor/github.com/cenkalti/backoff/v4/retry.go
generated
vendored
146
vendor/github.com/cenkalti/backoff/v4/retry.go
generated
vendored
@ -1,146 +0,0 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// An OperationWithData is executing by RetryWithData() or RetryNotifyWithData().
|
||||
// The operation will be retried using a backoff policy if it returns an error.
|
||||
type OperationWithData[T any] func() (T, error)
|
||||
|
||||
// An Operation is executing by Retry() or RetryNotify().
|
||||
// The operation will be retried using a backoff policy if it returns an error.
|
||||
type Operation func() error
|
||||
|
||||
func (o Operation) withEmptyData() OperationWithData[struct{}] {
|
||||
return func() (struct{}, error) {
|
||||
return struct{}{}, o()
|
||||
}
|
||||
}
|
||||
|
||||
// Notify is a notify-on-error function. It receives an operation error and
|
||||
// backoff delay if the operation failed (with an error).
|
||||
//
|
||||
// NOTE that if the backoff policy stated to stop retrying,
|
||||
// the notify function isn't called.
|
||||
type Notify func(error, time.Duration)
|
||||
|
||||
// Retry the operation o until it does not return error or BackOff stops.
|
||||
// o is guaranteed to be run at least once.
|
||||
//
|
||||
// If o returns a *PermanentError, the operation is not retried, and the
|
||||
// wrapped error is returned.
|
||||
//
|
||||
// Retry sleeps the goroutine for the duration returned by BackOff after a
|
||||
// failed operation returns.
|
||||
func Retry(o Operation, b BackOff) error {
|
||||
return RetryNotify(o, b, nil)
|
||||
}
|
||||
|
||||
// RetryWithData is like Retry but returns data in the response too.
|
||||
func RetryWithData[T any](o OperationWithData[T], b BackOff) (T, error) {
|
||||
return RetryNotifyWithData(o, b, nil)
|
||||
}
|
||||
|
||||
// RetryNotify calls notify function with the error and wait duration
|
||||
// for each failed attempt before sleep.
|
||||
func RetryNotify(operation Operation, b BackOff, notify Notify) error {
|
||||
return RetryNotifyWithTimer(operation, b, notify, nil)
|
||||
}
|
||||
|
||||
// RetryNotifyWithData is like RetryNotify but returns data in the response too.
|
||||
func RetryNotifyWithData[T any](operation OperationWithData[T], b BackOff, notify Notify) (T, error) {
|
||||
return doRetryNotify(operation, b, notify, nil)
|
||||
}
|
||||
|
||||
// RetryNotifyWithTimer calls notify function with the error and wait duration using the given Timer
|
||||
// for each failed attempt before sleep.
|
||||
// A default timer that uses system timer is used when nil is passed.
|
||||
func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error {
|
||||
_, err := doRetryNotify(operation.withEmptyData(), b, notify, t)
|
||||
return err
|
||||
}
|
||||
|
||||
// RetryNotifyWithTimerAndData is like RetryNotifyWithTimer but returns data in the response too.
|
||||
func RetryNotifyWithTimerAndData[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) {
|
||||
return doRetryNotify(operation, b, notify, t)
|
||||
}
|
||||
|
||||
func doRetryNotify[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error) {
|
||||
var (
|
||||
err error
|
||||
next time.Duration
|
||||
res T
|
||||
)
|
||||
if t == nil {
|
||||
t = &defaultTimer{}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
t.Stop()
|
||||
}()
|
||||
|
||||
ctx := getContext(b)
|
||||
|
||||
b.Reset()
|
||||
for {
|
||||
res, err = operation()
|
||||
if err == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
var permanent *PermanentError
|
||||
if errors.As(err, &permanent) {
|
||||
return res, permanent.Err
|
||||
}
|
||||
|
||||
if next = b.NextBackOff(); next == Stop {
|
||||
if cerr := ctx.Err(); cerr != nil {
|
||||
return res, cerr
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
if notify != nil {
|
||||
notify(err, next)
|
||||
}
|
||||
|
||||
t.Start(next)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return res, ctx.Err()
|
||||
case <-t.C():
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PermanentError signals that the operation should not be retried.
|
||||
type PermanentError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *PermanentError) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
func (e *PermanentError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
func (e *PermanentError) Is(target error) bool {
|
||||
_, ok := target.(*PermanentError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Permanent wraps the given err in a *PermanentError.
|
||||
func Permanent(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &PermanentError{
|
||||
Err: err,
|
||||
}
|
||||
}
|
38
vendor/github.com/cenkalti/backoff/v4/tries.go
generated
vendored
38
vendor/github.com/cenkalti/backoff/v4/tries.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
package backoff
|
||||
|
||||
import "time"
|
||||
|
||||
/*
|
||||
WithMaxRetries creates a wrapper around another BackOff, which will
|
||||
return Stop if NextBackOff() has been called too many times since
|
||||
the last time Reset() was called
|
||||
|
||||
Note: Implementation is not thread-safe.
|
||||
*/
|
||||
func WithMaxRetries(b BackOff, max uint64) BackOff {
|
||||
return &backOffTries{delegate: b, maxTries: max}
|
||||
}
|
||||
|
||||
type backOffTries struct {
|
||||
delegate BackOff
|
||||
maxTries uint64
|
||||
numTries uint64
|
||||
}
|
||||
|
||||
func (b *backOffTries) NextBackOff() time.Duration {
|
||||
if b.maxTries == 0 {
|
||||
return Stop
|
||||
}
|
||||
if b.maxTries > 0 {
|
||||
if b.maxTries <= b.numTries {
|
||||
return Stop
|
||||
}
|
||||
b.numTries++
|
||||
}
|
||||
return b.delegate.NextBackOff()
|
||||
}
|
||||
|
||||
func (b *backOffTries) Reset() {
|
||||
b.numTries = 0
|
||||
b.delegate.Reset()
|
||||
}
|
29
vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md
generated
vendored
Normal file
29
vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [5.0.0] - 2024-12-19
|
||||
|
||||
### Added
|
||||
|
||||
- RetryAfterError can be returned from an operation to indicate how long to wait before the next retry.
|
||||
|
||||
### Changed
|
||||
|
||||
- Retry function now accepts additional options for specifying max number of tries and max elapsed time.
|
||||
- Retry function now accepts a context.Context.
|
||||
- Operation function signature changed to return result (any type) and error.
|
||||
|
||||
### Removed
|
||||
|
||||
- RetryNotify* and RetryWithData functions. Only single Retry function remains.
|
||||
- Optional arguments from ExponentialBackoff constructor.
|
||||
- Clock and Timer interfaces.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The original error is returned from Retry if there's a PermanentError. (#144)
|
||||
- The Retry function respects the wrapped PermanentError. (#140)
|
@ -1,4 +1,4 @@
|
||||
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Coverage Status][coveralls image]][coveralls]
|
||||
# Exponential Backoff [![GoDoc][godoc image]][godoc]
|
||||
|
||||
This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client].
|
||||
|
||||
@ -9,9 +9,11 @@ The retries exponentially increase and stop increasing when a certain threshold
|
||||
|
||||
## Usage
|
||||
|
||||
Import path is `github.com/cenkalti/backoff/v4`. Please note the version part at the end.
|
||||
Import path is `github.com/cenkalti/backoff/v5`. Please note the version part at the end.
|
||||
|
||||
Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation.
|
||||
For most cases, use `Retry` function. See [example_test.go][example] for an example.
|
||||
|
||||
If you have specific needs, copy `Retry` function (from [retry.go][retry-src]) into your code and modify it as needed.
|
||||
|
||||
## Contributing
|
||||
|
||||
@ -19,12 +21,11 @@ Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation.
|
||||
* Please don't send a PR without opening an issue and discussing it first.
|
||||
* If proposed change is not a common use case, I will probably not accept it.
|
||||
|
||||
[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4
|
||||
[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v5
|
||||
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
|
||||
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
|
||||
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
|
||||
|
||||
[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java
|
||||
[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff
|
||||
|
||||
[advanced example]: https://pkg.go.dev/github.com/cenkalti/backoff/v4?tab=doc#pkg-examples
|
||||
[retry-src]: https://github.com/cenkalti/backoff/blob/v5/retry.go
|
||||
[example]: https://github.com/cenkalti/backoff/blob/v5/example_test.go
|
@ -15,16 +15,16 @@ import "time"
|
||||
// BackOff is a backoff policy for retrying an operation.
|
||||
type BackOff interface {
|
||||
// NextBackOff returns the duration to wait before retrying the operation,
|
||||
// or backoff. Stop to indicate that no more retries should be made.
|
||||
// backoff.Stop to indicate that no more retries should be made.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// duration := backoff.NextBackOff();
|
||||
// if (duration == backoff.Stop) {
|
||||
// // Do not retry operation.
|
||||
// } else {
|
||||
// // Sleep for duration and retry operation.
|
||||
// }
|
||||
// duration := backoff.NextBackOff()
|
||||
// if duration == backoff.Stop {
|
||||
// // Do not retry operation.
|
||||
// } else {
|
||||
// // Sleep for duration and retry operation.
|
||||
// }
|
||||
//
|
||||
NextBackOff() time.Duration
|
||||
|
46
vendor/github.com/cenkalti/backoff/v5/error.go
generated
vendored
Normal file
46
vendor/github.com/cenkalti/backoff/v5/error.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PermanentError signals that the operation should not be retried.
|
||||
type PermanentError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
// Permanent wraps the given err in a *PermanentError.
|
||||
func Permanent(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &PermanentError{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns a string representation of the Permanent error.
|
||||
func (e *PermanentError) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// Unwrap returns the wrapped error.
|
||||
func (e *PermanentError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// RetryAfterError signals that the operation should be retried after the given duration.
|
||||
type RetryAfterError struct {
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
// RetryAfter returns a RetryAfter error that specifies how long to wait before retrying.
|
||||
func RetryAfter(seconds int) error {
|
||||
return &RetryAfterError{Duration: time.Duration(seconds) * time.Second}
|
||||
}
|
||||
|
||||
// Error returns a string representation of the RetryAfter error.
|
||||
func (e *RetryAfterError) Error() string {
|
||||
return fmt.Sprintf("retry after %s", e.Duration)
|
||||
}
|
118
vendor/github.com/cenkalti/backoff/v5/exponential.go
generated
vendored
Normal file
118
vendor/github.com/cenkalti/backoff/v5/exponential.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
ExponentialBackOff is a backoff implementation that increases the backoff
|
||||
period for each retry attempt using a randomization function that grows exponentially.
|
||||
|
||||
NextBackOff() is calculated using the following formula:
|
||||
|
||||
randomized interval =
|
||||
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
||||
|
||||
In other words NextBackOff() will range between the randomization factor
|
||||
percentage below and above the retry interval.
|
||||
|
||||
For example, given the following parameters:
|
||||
|
||||
RetryInterval = 2
|
||||
RandomizationFactor = 0.5
|
||||
Multiplier = 2
|
||||
|
||||
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
|
||||
multiplied by the exponential, that is, between 2 and 6 seconds.
|
||||
|
||||
Note: MaxInterval caps the RetryInterval and not the randomized interval.
|
||||
|
||||
Example: Given the following default arguments, for 9 tries the sequence will be:
|
||||
|
||||
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
||||
|
||||
1 0.5 [0.25, 0.75]
|
||||
2 0.75 [0.375, 1.125]
|
||||
3 1.125 [0.562, 1.687]
|
||||
4 1.687 [0.8435, 2.53]
|
||||
5 2.53 [1.265, 3.795]
|
||||
6 3.795 [1.897, 5.692]
|
||||
7 5.692 [2.846, 8.538]
|
||||
8 8.538 [4.269, 12.807]
|
||||
9 12.807 [6.403, 19.210]
|
||||
|
||||
Note: Implementation is not thread-safe.
|
||||
*/
|
||||
type ExponentialBackOff struct {
|
||||
InitialInterval time.Duration
|
||||
RandomizationFactor float64
|
||||
Multiplier float64
|
||||
MaxInterval time.Duration
|
||||
|
||||
currentInterval time.Duration
|
||||
}
|
||||
|
||||
// Default values for ExponentialBackOff.
|
||||
const (
|
||||
DefaultInitialInterval = 500 * time.Millisecond
|
||||
DefaultRandomizationFactor = 0.5
|
||||
DefaultMultiplier = 1.5
|
||||
DefaultMaxInterval = 60 * time.Second
|
||||
)
|
||||
|
||||
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
|
||||
func NewExponentialBackOff() *ExponentialBackOff {
|
||||
return &ExponentialBackOff{
|
||||
InitialInterval: DefaultInitialInterval,
|
||||
RandomizationFactor: DefaultRandomizationFactor,
|
||||
Multiplier: DefaultMultiplier,
|
||||
MaxInterval: DefaultMaxInterval,
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the interval back to the initial retry interval and restarts the timer.
|
||||
// Reset must be called before using b.
|
||||
func (b *ExponentialBackOff) Reset() {
|
||||
b.currentInterval = b.InitialInterval
|
||||
}
|
||||
|
||||
// NextBackOff calculates the next backoff interval using the formula:
|
||||
//
|
||||
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
||||
func (b *ExponentialBackOff) NextBackOff() time.Duration {
|
||||
if b.currentInterval == 0 {
|
||||
b.currentInterval = b.InitialInterval
|
||||
}
|
||||
|
||||
next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
|
||||
b.incrementCurrentInterval()
|
||||
return next
|
||||
}
|
||||
|
||||
// Increments the current interval by multiplying it with the multiplier.
|
||||
func (b *ExponentialBackOff) incrementCurrentInterval() {
|
||||
// Check for overflow, if overflow is detected set the current interval to the max interval.
|
||||
if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier {
|
||||
b.currentInterval = b.MaxInterval
|
||||
} else {
|
||||
b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a random value from the following interval:
|
||||
//
|
||||
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
||||
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
|
||||
if randomizationFactor == 0 {
|
||||
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
|
||||
}
|
||||
var delta = randomizationFactor * float64(currentInterval)
|
||||
var minInterval = float64(currentInterval) - delta
|
||||
var maxInterval = float64(currentInterval) + delta
|
||||
|
||||
// Get a random value from the range [minInterval, maxInterval].
|
||||
// The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then
|
||||
// we want a 33% chance for selecting either 1, 2 or 3.
|
||||
return time.Duration(minInterval + (random * (maxInterval - minInterval + 1)))
|
||||
}
|
139
vendor/github.com/cenkalti/backoff/v5/retry.go
generated
vendored
Normal file
139
vendor/github.com/cenkalti/backoff/v5/retry.go
generated
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultMaxElapsedTime sets a default limit for the total retry duration.
|
||||
const DefaultMaxElapsedTime = 15 * time.Minute
|
||||
|
||||
// Operation is a function that attempts an operation and may be retried.
|
||||
type Operation[T any] func() (T, error)
|
||||
|
||||
// Notify is a function called on operation error with the error and backoff duration.
|
||||
type Notify func(error, time.Duration)
|
||||
|
||||
// retryOptions holds configuration settings for the retry mechanism.
|
||||
type retryOptions struct {
|
||||
BackOff BackOff // Strategy for calculating backoff periods.
|
||||
Timer timer // Timer to manage retry delays.
|
||||
Notify Notify // Optional function to notify on each retry error.
|
||||
MaxTries uint // Maximum number of retry attempts.
|
||||
MaxElapsedTime time.Duration // Maximum total time for all retries.
|
||||
}
|
||||
|
||||
type RetryOption func(*retryOptions)
|
||||
|
||||
// WithBackOff configures a custom backoff strategy.
|
||||
func WithBackOff(b BackOff) RetryOption {
|
||||
return func(args *retryOptions) {
|
||||
args.BackOff = b
|
||||
}
|
||||
}
|
||||
|
||||
// withTimer sets a custom timer for managing delays between retries.
|
||||
func withTimer(t timer) RetryOption {
|
||||
return func(args *retryOptions) {
|
||||
args.Timer = t
|
||||
}
|
||||
}
|
||||
|
||||
// WithNotify sets a notification function to handle retry errors.
|
||||
func WithNotify(n Notify) RetryOption {
|
||||
return func(args *retryOptions) {
|
||||
args.Notify = n
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxTries limits the number of all attempts.
|
||||
func WithMaxTries(n uint) RetryOption {
|
||||
return func(args *retryOptions) {
|
||||
args.MaxTries = n
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxElapsedTime limits the total duration for retry attempts.
|
||||
func WithMaxElapsedTime(d time.Duration) RetryOption {
|
||||
return func(args *retryOptions) {
|
||||
args.MaxElapsedTime = d
|
||||
}
|
||||
}
|
||||
|
||||
// Retry attempts the operation until success, a permanent error, or backoff completion.
|
||||
// It ensures the operation is executed at least once.
|
||||
//
|
||||
// Returns the operation result or error if retries are exhausted or context is cancelled.
|
||||
func Retry[T any](ctx context.Context, operation Operation[T], opts ...RetryOption) (T, error) {
|
||||
// Initialize default retry options.
|
||||
args := &retryOptions{
|
||||
BackOff: NewExponentialBackOff(),
|
||||
Timer: &defaultTimer{},
|
||||
MaxElapsedTime: DefaultMaxElapsedTime,
|
||||
}
|
||||
|
||||
// Apply user-provided options to the default settings.
|
||||
for _, opt := range opts {
|
||||
opt(args)
|
||||
}
|
||||
|
||||
defer args.Timer.Stop()
|
||||
|
||||
startedAt := time.Now()
|
||||
args.BackOff.Reset()
|
||||
for numTries := uint(1); ; numTries++ {
|
||||
// Execute the operation.
|
||||
res, err := operation()
|
||||
if err == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Stop retrying if maximum tries exceeded.
|
||||
if args.MaxTries > 0 && numTries >= args.MaxTries {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Handle permanent errors without retrying.
|
||||
var permanent *PermanentError
|
||||
if errors.As(err, &permanent) {
|
||||
return res, permanent.Unwrap()
|
||||
}
|
||||
|
||||
// Stop retrying if context is cancelled.
|
||||
if cerr := context.Cause(ctx); cerr != nil {
|
||||
return res, cerr
|
||||
}
|
||||
|
||||
// Calculate next backoff duration.
|
||||
next := args.BackOff.NextBackOff()
|
||||
if next == Stop {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Reset backoff if RetryAfterError is encountered.
|
||||
var retryAfter *RetryAfterError
|
||||
if errors.As(err, &retryAfter) {
|
||||
next = retryAfter.Duration
|
||||
args.BackOff.Reset()
|
||||
}
|
||||
|
||||
// Stop retrying if maximum elapsed time exceeded.
|
||||
if args.MaxElapsedTime > 0 && time.Since(startedAt)+next > args.MaxElapsedTime {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Notify on error if a notifier function is provided.
|
||||
if args.Notify != nil {
|
||||
args.Notify(err, next)
|
||||
}
|
||||
|
||||
// Wait for the next backoff period or context cancellation.
|
||||
args.Timer.Start(next)
|
||||
select {
|
||||
case <-args.Timer.C():
|
||||
case <-ctx.Done():
|
||||
return res, context.Cause(ctx)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package backoff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -14,8 +13,7 @@ type Ticker struct {
|
||||
C <-chan time.Time
|
||||
c chan time.Time
|
||||
b BackOff
|
||||
ctx context.Context
|
||||
timer Timer
|
||||
timer timer
|
||||
stop chan struct{}
|
||||
stopOnce sync.Once
|
||||
}
|
||||
@ -27,22 +25,12 @@ type Ticker struct {
|
||||
// provided backoff policy (notably calling NextBackOff or Reset)
|
||||
// while the ticker is running.
|
||||
func NewTicker(b BackOff) *Ticker {
|
||||
return NewTickerWithTimer(b, &defaultTimer{})
|
||||
}
|
||||
|
||||
// NewTickerWithTimer returns a new Ticker with a custom timer.
|
||||
// A default timer that uses system timer is used when nil is passed.
|
||||
func NewTickerWithTimer(b BackOff, timer Timer) *Ticker {
|
||||
if timer == nil {
|
||||
timer = &defaultTimer{}
|
||||
}
|
||||
c := make(chan time.Time)
|
||||
t := &Ticker{
|
||||
C: c,
|
||||
c: c,
|
||||
b: b,
|
||||
ctx: getContext(b),
|
||||
timer: timer,
|
||||
timer: &defaultTimer{},
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
t.b.Reset()
|
||||
@ -73,8 +61,6 @@ func (t *Ticker) run() {
|
||||
case <-t.stop:
|
||||
t.c = nil // Prevent future ticks from being sent to the channel.
|
||||
return
|
||||
case <-t.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package backoff
|
||||
|
||||
import "time"
|
||||
|
||||
type Timer interface {
|
||||
type timer interface {
|
||||
Start(duration time.Duration)
|
||||
Stop()
|
||||
C() <-chan time.Time
|
40
vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml
generated
vendored
40
vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml
generated
vendored
@ -1,40 +0,0 @@
|
||||
run:
|
||||
tests: false
|
||||
issues-exit-code: 0
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- exhaustive
|
||||
- goconst
|
||||
- godot
|
||||
- godox
|
||||
- mnd
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- wrapcheck
|
||||
|
||||
# disable default linters, they are already enabled in .golangci.yml
|
||||
disable:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unused
|
40
vendor/github.com/charmbracelet/bubbletea/.golangci.yml
generated
vendored
40
vendor/github.com/charmbracelet/bubbletea/.golangci.yml
generated
vendored
@ -1,24 +1,22 @@
|
||||
version: "2"
|
||||
run:
|
||||
tests: false
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- gofumpt
|
||||
- goimports
|
||||
- exhaustive
|
||||
- goconst
|
||||
- godot
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
@ -26,3 +24,17 @@ linters:
|
||||
- unconvert
|
||||
- unparam
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- common-false-positives
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gofumpt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
|
8
vendor/github.com/charmbracelet/bubbletea/README.md
generated
vendored
8
vendor/github.com/charmbracelet/bubbletea/README.md
generated
vendored
@ -1,11 +1,15 @@
|
||||
# Bubble Tea
|
||||
|
||||
<p>
|
||||
<a href="https://stuff.charm.sh/bubbletea/bubbletea-4k.png"><img src="https://github.com/charmbracelet/bubbletea/assets/25087/108d4fdb-d554-4910-abed-2a5f5586a60e" width="313" alt="Bubble Tea Title Treatment"></a><br>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://stuff.charm.sh/bubbletea/bubble-tea-v2-light.png" width="308">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://stuff.charm.sh/bubbletea/bubble-tea-v2-dark.png" width="312">
|
||||
<img src="https://stuff.charm.sh/bubbletea/bubble-tea-v2-light.png" width="308" />
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://github.com/charmbracelet/bubbletea/releases"><img src="https://img.shields.io/github/release/charmbracelet/bubbletea.svg" alt="Latest Release"></a>
|
||||
<a href="https://pkg.go.dev/github.com/charmbracelet/bubbletea?tab=doc"><img src="https://godoc.org/github.com/charmbracelet/bubbletea?status.svg" alt="GoDoc"></a>
|
||||
<a href="https://github.com/charmbracelet/bubbletea/actions"><img src="https://github.com/charmbracelet/bubbletea/actions/workflows/build.yml/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://www.phorm.ai/query?projectId=a0e324b6-b706-4546-b951-6671ea60c13f"><img src="https://stuff.charm.sh/misc/phorm-badge.svg" alt="phorm.ai"></a>
|
||||
</p>
|
||||
|
||||
The fun, functional and stateful way to build terminal apps. A Go framework
|
||||
|
14
vendor/github.com/charmbracelet/bubbletea/Taskfile.yaml
generated
vendored
Normal file
14
vendor/github.com/charmbracelet/bubbletea/Taskfile.yaml
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# https://taskfile.dev
|
||||
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
lint:
|
||||
desc: Run lint
|
||||
cmds:
|
||||
- golangci-lint run
|
||||
|
||||
test:
|
||||
desc: Run tests
|
||||
cmds:
|
||||
- go test ./... {{.CLI_ARGS}}
|
4
vendor/github.com/charmbracelet/bubbletea/exec.go
generated
vendored
4
vendor/github.com/charmbracelet/bubbletea/exec.go
generated
vendored
@ -114,6 +114,7 @@ func (p *Program) exec(c ExecCommand, fn ExecCallback) {
|
||||
|
||||
// Execute system command.
|
||||
if err := c.Run(); err != nil {
|
||||
p.renderer.resetLinesRendered()
|
||||
_ = p.RestoreTerminal() // also try to restore the terminal.
|
||||
if fn != nil {
|
||||
go p.Send(fn(err))
|
||||
@ -121,6 +122,9 @@ func (p *Program) exec(c ExecCommand, fn ExecCallback) {
|
||||
return
|
||||
}
|
||||
|
||||
// Maintain the existing output from the command
|
||||
p.renderer.resetLinesRendered()
|
||||
|
||||
// Have the program re-capture input.
|
||||
err := p.RestoreTerminal()
|
||||
if fn != nil {
|
||||
|
7
vendor/github.com/charmbracelet/bubbletea/inputreader_other.go
generated
vendored
7
vendor/github.com/charmbracelet/bubbletea/inputreader_other.go
generated
vendored
@ -4,11 +4,16 @@
|
||||
package tea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/muesli/cancelreader"
|
||||
)
|
||||
|
||||
func newInputReader(r io.Reader, _ bool) (cancelreader.CancelReader, error) {
|
||||
return cancelreader.NewReader(r)
|
||||
cr, err := cancelreader.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bubbletea: error creating cancel reader: %w", err)
|
||||
}
|
||||
return cr, nil
|
||||
}
|
||||
|
2
vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/inputreader_windows.go
generated
vendored
@ -67,6 +67,8 @@ func newInputReader(r io.Reader, enableMouse bool) (cancelreader.CancelReader, e
|
||||
func (r *conInputReader) Cancel() bool {
|
||||
r.setCanceled()
|
||||
|
||||
// Warning: These cancel methods do not reliably work on console input
|
||||
// and should not be counted on.
|
||||
return windows.CancelIoEx(r.conin, nil) == nil || windows.CancelIo(r.conin) == nil
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/charmbracelet/bubbletea/key.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/key.go
generated
vendored
@ -622,7 +622,7 @@ func detectOneMsg(b []byte, canHaveMoreData bool) (w int, msg Msg) {
|
||||
case '<':
|
||||
if matchIndices := mouseSGRRegex.FindSubmatchIndex(b[3:]); matchIndices != nil {
|
||||
// SGR mouse events length is the length of the match plus the length of the escape sequence
|
||||
mouseEventSGRLen := matchIndices[1] + 3 //nolint:gomnd
|
||||
mouseEventSGRLen := matchIndices[1] + 3 //nolint:mnd
|
||||
return mouseEventSGRLen, MouseMsg(parseSGRMouseEvent(b))
|
||||
}
|
||||
}
|
||||
|
5
vendor/github.com/charmbracelet/bubbletea/key_sequences.go
generated
vendored
5
vendor/github.com/charmbracelet/bubbletea/key_sequences.go
generated
vendored
@ -119,13 +119,12 @@ func detectBracketedPaste(input []byte) (hasBp bool, width int, msg Msg) {
|
||||
}
|
||||
|
||||
// detectReportFocus detects a focus report sequence.
|
||||
// nolint: gomnd
|
||||
func detectReportFocus(input []byte) (hasRF bool, width int, msg Msg) {
|
||||
switch {
|
||||
case bytes.Equal(input, []byte("\x1b[I")):
|
||||
return true, 3, FocusMsg{}
|
||||
return true, 3, FocusMsg{} //nolint:mnd
|
||||
case bytes.Equal(input, []byte("\x1b[O")):
|
||||
return true, 3, BlurMsg{}
|
||||
return true, 3, BlurMsg{} //nolint:mnd
|
||||
}
|
||||
return false, 0, nil
|
||||
}
|
||||
|
103
vendor/github.com/charmbracelet/bubbletea/key_windows.go
generated
vendored
103
vendor/github.com/charmbracelet/bubbletea/key_windows.go
generated
vendored
@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/erikgeiser/coninput"
|
||||
localereader "github.com/mattn/go-localereader"
|
||||
@ -25,14 +26,10 @@ func readConInputs(ctx context.Context, msgsch chan<- Msg, con *conInputReader)
|
||||
var ps coninput.ButtonState // keep track of previous mouse state
|
||||
var ws coninput.WindowBufferSizeEventRecord // keep track of the last window size event
|
||||
for {
|
||||
events, err := coninput.ReadNConsoleInputs(con.conin, 16)
|
||||
events, err := peekAndReadConsInput(con)
|
||||
if err != nil {
|
||||
if con.isCanceled() {
|
||||
return cancelreader.ErrCanceled
|
||||
}
|
||||
return fmt.Errorf("read coninput events: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, event := range events {
|
||||
var msgs []Msg
|
||||
switch e := event.Unwrap().(type) {
|
||||
@ -87,13 +84,57 @@ func readConInputs(ctx context.Context, msgsch chan<- Msg, con *conInputReader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("coninput context error: %w", err)
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Peek for new input in a tight loop and then read the input.
|
||||
// windows.CancelIo* does not work reliably so peek first and only use the data if
|
||||
// the console input is not cancelled.
|
||||
func peekAndReadConsInput(con *conInputReader) ([]coninput.InputRecord, error) {
|
||||
events, err := peekConsInput(con)
|
||||
if err != nil {
|
||||
return events, err
|
||||
}
|
||||
events, err = coninput.ReadNConsoleInputs(con.conin, intToUint32OrDie(len(events)))
|
||||
if con.isCanceled() {
|
||||
return events, cancelreader.ErrCanceled
|
||||
}
|
||||
if err != nil {
|
||||
return events, fmt.Errorf("read coninput events: %w", err)
|
||||
}
|
||||
return events, nil
|
||||
}
|
||||
|
||||
// Convert i to unit32 or panic if it cannot be converted. Check satisifes lint G115.
|
||||
func intToUint32OrDie(i int) uint32 {
|
||||
if i < 0 {
|
||||
panic("cannot convert numEvents " + fmt.Sprint(i) + " to uint32")
|
||||
}
|
||||
return uint32(i)
|
||||
}
|
||||
|
||||
// Keeps peeking until there is data or the input is cancelled.
|
||||
func peekConsInput(con *conInputReader) ([]coninput.InputRecord, error) {
|
||||
for {
|
||||
events, err := coninput.PeekNConsoleInputs(con.conin, 16)
|
||||
if con.isCanceled() {
|
||||
return events, cancelreader.ErrCanceled
|
||||
}
|
||||
if err != nil {
|
||||
return events, fmt.Errorf("peek coninput events: %w", err)
|
||||
}
|
||||
if len(events) > 0 {
|
||||
return events, nil
|
||||
}
|
||||
// Sleep for a bit to avoid busy waiting.
|
||||
time.Sleep(16 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func mouseEventButton(p, s coninput.ButtonState) (button MouseButton, action MouseAction) {
|
||||
btn := p ^ s
|
||||
action = MouseActionPress
|
||||
@ -114,7 +155,7 @@ func mouseEventButton(p, s coninput.ButtonState) (button MouseButton, action Mou
|
||||
case s&coninput.FROM_LEFT_4TH_BUTTON_PRESSED > 0:
|
||||
button = MouseButtonForward
|
||||
}
|
||||
return
|
||||
return button, action
|
||||
}
|
||||
|
||||
switch {
|
||||
@ -147,7 +188,7 @@ func mouseEvent(p coninput.ButtonState, e coninput.MouseEventRecord) MouseMsg {
|
||||
if ev.Action == MouseActionRelease {
|
||||
ev.Type = MouseRelease
|
||||
}
|
||||
switch ev.Button {
|
||||
switch ev.Button { //nolint:exhaustive
|
||||
case MouseButtonLeft:
|
||||
ev.Type = MouseLeft
|
||||
case MouseButtonMiddle:
|
||||
@ -190,7 +231,7 @@ func keyType(e coninput.KeyEventRecord) KeyType {
|
||||
shiftPressed := e.ControlKeyState.Contains(coninput.SHIFT_PRESSED)
|
||||
ctrlPressed := e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED | coninput.RIGHT_CTRL_PRESSED)
|
||||
|
||||
switch code {
|
||||
switch code { //nolint:exhaustive
|
||||
case coninput.VK_RETURN:
|
||||
return KeyEnter
|
||||
case coninput.VK_BACK:
|
||||
@ -276,6 +317,46 @@ func keyType(e coninput.KeyEventRecord) KeyType {
|
||||
return KeyPgDown
|
||||
case coninput.VK_DELETE:
|
||||
return KeyDelete
|
||||
case coninput.VK_F1:
|
||||
return KeyF1
|
||||
case coninput.VK_F2:
|
||||
return KeyF2
|
||||
case coninput.VK_F3:
|
||||
return KeyF3
|
||||
case coninput.VK_F4:
|
||||
return KeyF4
|
||||
case coninput.VK_F5:
|
||||
return KeyF5
|
||||
case coninput.VK_F6:
|
||||
return KeyF6
|
||||
case coninput.VK_F7:
|
||||
return KeyF7
|
||||
case coninput.VK_F8:
|
||||
return KeyF8
|
||||
case coninput.VK_F9:
|
||||
return KeyF9
|
||||
case coninput.VK_F10:
|
||||
return KeyF10
|
||||
case coninput.VK_F11:
|
||||
return KeyF11
|
||||
case coninput.VK_F12:
|
||||
return KeyF12
|
||||
case coninput.VK_F13:
|
||||
return KeyF13
|
||||
case coninput.VK_F14:
|
||||
return KeyF14
|
||||
case coninput.VK_F15:
|
||||
return KeyF15
|
||||
case coninput.VK_F16:
|
||||
return KeyF16
|
||||
case coninput.VK_F17:
|
||||
return KeyF17
|
||||
case coninput.VK_F18:
|
||||
return KeyF18
|
||||
case coninput.VK_F19:
|
||||
return KeyF19
|
||||
case coninput.VK_F20:
|
||||
return KeyF20
|
||||
default:
|
||||
switch {
|
||||
case e.ControlKeyState.Contains(coninput.LEFT_CTRL_PRESSED) && e.ControlKeyState.Contains(coninput.RIGHT_ALT_PRESSED):
|
||||
@ -348,7 +429,7 @@ func keyType(e coninput.KeyEventRecord) KeyType {
|
||||
return KeyCtrlUnderscore
|
||||
}
|
||||
|
||||
switch code {
|
||||
switch code { //nolint:exhaustive
|
||||
case coninput.VK_OEM_4:
|
||||
return KeyCtrlOpenBracket
|
||||
case coninput.VK_OEM_6:
|
||||
|
2
vendor/github.com/charmbracelet/bubbletea/logging.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/logging.go
generated
vendored
@ -33,7 +33,7 @@ type LogOptionsSetter interface {
|
||||
|
||||
// LogToFileWith does allows to call LogToFile with a custom LogOptionsSetter.
|
||||
func LogToFileWith(path string, prefix string, log LogOptionsSetter) (*os.File, error) {
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o600) //nolint:gomnd
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o600) //nolint:mnd
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening file for logging: %w", err)
|
||||
}
|
||||
|
2
vendor/github.com/charmbracelet/bubbletea/mouse.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/mouse.go
generated
vendored
@ -172,7 +172,7 @@ const (
|
||||
func parseSGRMouseEvent(buf []byte) MouseEvent {
|
||||
str := string(buf[3:])
|
||||
matches := mouseSGRRegex.FindStringSubmatch(str)
|
||||
if len(matches) != 5 { //nolint:gomnd
|
||||
if len(matches) != 5 { //nolint:mnd
|
||||
// Unreachable, we already checked the regex in `detectOneMsg`.
|
||||
panic("invalid mouse event")
|
||||
}
|
||||
|
1
vendor/github.com/charmbracelet/bubbletea/nil_renderer.go
generated
vendored
1
vendor/github.com/charmbracelet/bubbletea/nil_renderer.go
generated
vendored
@ -26,3 +26,4 @@ func (n nilRenderer) setWindowTitle(_ string) {}
|
||||
func (n nilRenderer) reportFocus() bool { return false }
|
||||
func (n nilRenderer) enableReportFocus() {}
|
||||
func (n nilRenderer) disableReportFocus() {}
|
||||
func (n nilRenderer) resetLinesRendered() {}
|
||||
|
2
vendor/github.com/charmbracelet/bubbletea/options.go
generated
vendored
2
vendor/github.com/charmbracelet/bubbletea/options.go
generated
vendored
@ -19,7 +19,7 @@ type ProgramOption func(*Program)
|
||||
// cancelled it will exit with an error ErrProgramKilled.
|
||||
func WithContext(ctx context.Context) ProgramOption {
|
||||
return func(p *Program) {
|
||||
p.ctx = ctx
|
||||
p.externalCtx = ctx
|
||||
}
|
||||
}
|
||||
|
||||
|
3
vendor/github.com/charmbracelet/bubbletea/renderer.go
generated
vendored
3
vendor/github.com/charmbracelet/bubbletea/renderer.go
generated
vendored
@ -79,6 +79,9 @@ type renderer interface {
|
||||
|
||||
// disableReportFocus stops reporting focus events to the program.
|
||||
disableReportFocus()
|
||||
|
||||
// resetLinesRendered ensures exec output remains on screen on exit
|
||||
resetLinesRendered()
|
||||
}
|
||||
|
||||
// repaintMsg forces a full repaint.
|
||||
|
4
vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
generated
vendored
4
vendor/github.com/charmbracelet/bubbletea/standard_renderer.go
generated
vendored
@ -545,6 +545,10 @@ func (r *standardRenderer) clearIgnoredLines() {
|
||||
r.ignoreLines = nil
|
||||
}
|
||||
|
||||
func (r *standardRenderer) resetLinesRendered() {
|
||||
r.linesRendered = 0
|
||||
}
|
||||
|
||||
// insertTop effectively scrolls up. It inserts lines at the top of a given
|
||||
// area designated to be a scrollable region, pushing everything else down.
|
||||
// This is roughly how ncurses does it.
|
||||
|
119
vendor/github.com/charmbracelet/bubbletea/tea.go
generated
vendored
119
vendor/github.com/charmbracelet/bubbletea/tea.go
generated
vendored
@ -27,6 +27,9 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// ErrProgramPanic is returned by [Program.Run] when the program recovers from a panic.
|
||||
var ErrProgramPanic = errors.New("program experienced a panic")
|
||||
|
||||
// ErrProgramKilled is returned by [Program.Run] when the program gets killed.
|
||||
var ErrProgramKilled = errors.New("program was killed")
|
||||
|
||||
@ -147,6 +150,12 @@ type Program struct {
|
||||
|
||||
inputType inputType
|
||||
|
||||
// externalCtx is a context that was passed in via WithContext, otherwise defaulting
|
||||
// to ctx.Background() (in case it was not), the internal context is derived from it.
|
||||
externalCtx context.Context
|
||||
|
||||
// ctx is the programs's internal context for signalling internal teardown.
|
||||
// It is built and derived from the externalCtx in NewProgram().
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
@ -243,11 +252,11 @@ func NewProgram(model Model, opts ...ProgramOption) *Program {
|
||||
|
||||
// A context can be provided with a ProgramOption, but if none was provided
|
||||
// we'll use the default background context.
|
||||
if p.ctx == nil {
|
||||
p.ctx = context.Background()
|
||||
if p.externalCtx == nil {
|
||||
p.externalCtx = context.Background()
|
||||
}
|
||||
// Initialize context and teardown channel.
|
||||
p.ctx, p.cancel = context.WithCancel(p.ctx)
|
||||
p.ctx, p.cancel = context.WithCancel(p.externalCtx)
|
||||
|
||||
// if no output was set, set it to stdout
|
||||
if p.output == nil {
|
||||
@ -346,7 +355,11 @@ func (p *Program) handleCommands(cmds chan Cmd) chan struct{} {
|
||||
go func() {
|
||||
// Recover from panics.
|
||||
if !p.startupOptions.has(withoutCatchPanics) {
|
||||
defer p.recoverFromPanic()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
p.recoverFromGoPanic(r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
msg := cmd() // this can be long.
|
||||
@ -422,7 +435,7 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
// work.
|
||||
if runtime.GOOS == "windows" && !p.mouseMode {
|
||||
p.mouseMode = true
|
||||
p.initCancelReader(true) //nolint:errcheck
|
||||
p.initCancelReader(true) //nolint:errcheck,gosec
|
||||
}
|
||||
|
||||
case disableMouseMsg:
|
||||
@ -433,7 +446,7 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
// mouse events.
|
||||
if runtime.GOOS == "windows" && p.mouseMode {
|
||||
p.mouseMode = false
|
||||
p.initCancelReader(true) //nolint:errcheck
|
||||
p.initCancelReader(true) //nolint:errcheck,gosec
|
||||
}
|
||||
|
||||
case showCursorMsg:
|
||||
@ -460,7 +473,11 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
|
||||
case BatchMsg:
|
||||
for _, cmd := range msg {
|
||||
cmds <- cmd
|
||||
select {
|
||||
case <-p.ctx.Done():
|
||||
return model, nil
|
||||
case cmds <- cmd:
|
||||
}
|
||||
}
|
||||
continue
|
||||
|
||||
@ -483,7 +500,7 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:errcheck
|
||||
//nolint:errcheck,gosec
|
||||
g.Wait() // wait for all commands from batch msg to finish
|
||||
continue
|
||||
}
|
||||
@ -506,7 +523,13 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
|
||||
var cmd Cmd
|
||||
model, cmd = model.Update(msg) // run update
|
||||
cmds <- cmd // process command (if any)
|
||||
|
||||
select {
|
||||
case <-p.ctx.Done():
|
||||
return model, nil
|
||||
case cmds <- cmd: // process command (if any)
|
||||
}
|
||||
|
||||
p.renderer.write(model.View()) // send view to renderer
|
||||
}
|
||||
}
|
||||
@ -515,11 +538,15 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
|
||||
// Run initializes the program and runs its event loops, blocking until it gets
|
||||
// terminated by either [Program.Quit], [Program.Kill], or its signal handler.
|
||||
// Returns the final model.
|
||||
func (p *Program) Run() (Model, error) {
|
||||
func (p *Program) Run() (returnModel Model, returnErr error) {
|
||||
p.handlers = channelHandlers{}
|
||||
cmds := make(chan Cmd)
|
||||
p.errs = make(chan error)
|
||||
p.finished = make(chan struct{}, 1)
|
||||
p.errs = make(chan error, 1)
|
||||
|
||||
p.finished = make(chan struct{})
|
||||
defer func() {
|
||||
close(p.finished)
|
||||
}()
|
||||
|
||||
defer p.cancel()
|
||||
|
||||
@ -568,7 +595,12 @@ func (p *Program) Run() (Model, error) {
|
||||
|
||||
// Recover from panics.
|
||||
if !p.startupOptions.has(withoutCatchPanics) {
|
||||
defer p.recoverFromPanic()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
returnErr = fmt.Errorf("%w: %w", ErrProgramKilled, ErrProgramPanic)
|
||||
p.recoverFromPanic(r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// If no renderer is set use the standard one.
|
||||
@ -645,11 +677,27 @@ func (p *Program) Run() (Model, error) {
|
||||
|
||||
// Run event loop, handle updates and draw.
|
||||
model, err := p.eventLoop(model, cmds)
|
||||
killed := p.ctx.Err() != nil || err != nil
|
||||
if killed && err == nil {
|
||||
err = fmt.Errorf("%w: %s", ErrProgramKilled, p.ctx.Err())
|
||||
|
||||
if err == nil && len(p.errs) > 0 {
|
||||
err = <-p.errs // Drain a leftover error in case eventLoop crashed
|
||||
}
|
||||
if err == nil {
|
||||
|
||||
killed := p.externalCtx.Err() != nil || p.ctx.Err() != nil || err != nil
|
||||
if killed {
|
||||
if err == nil && p.externalCtx.Err() != nil {
|
||||
// Return also as context error the cancellation of an external context.
|
||||
// This is the context the user knows about and should be able to act on.
|
||||
err = fmt.Errorf("%w: %w", ErrProgramKilled, p.externalCtx.Err())
|
||||
} else if err == nil && p.ctx.Err() != nil {
|
||||
// Return only that the program was killed (not the internal mechanism).
|
||||
// The user does not know or need to care about the internal program context.
|
||||
err = ErrProgramKilled
|
||||
} else {
|
||||
// Return that the program was killed and also the error that caused it.
|
||||
err = fmt.Errorf("%w: %w", ErrProgramKilled, err)
|
||||
}
|
||||
} else {
|
||||
// Graceful shutdown of the program (not killed):
|
||||
// Ensure we rendered the final state of the model.
|
||||
p.renderer.write(model.View())
|
||||
}
|
||||
@ -704,11 +752,11 @@ func (p *Program) Quit() {
|
||||
p.Send(Quit())
|
||||
}
|
||||
|
||||
// Kill stops the program immediately and restores the former terminal state.
|
||||
// Kill signals the program to stop immediately and restore the former terminal state.
|
||||
// The final render that you would normally see when quitting will be skipped.
|
||||
// [program.Run] returns a [ErrProgramKilled] error.
|
||||
func (p *Program) Kill() {
|
||||
p.shutdown(true)
|
||||
p.cancel()
|
||||
}
|
||||
|
||||
// Wait waits/blocks until the underlying Program finished shutting down.
|
||||
@ -717,7 +765,11 @@ func (p *Program) Wait() {
|
||||
}
|
||||
|
||||
// shutdown performs operations to free up resources and restore the terminal
|
||||
// to its original state.
|
||||
// to its original state. It is called once at the end of the program's lifetime.
|
||||
//
|
||||
// This method should not be called to signal the program to be killed/shutdown.
|
||||
// Doing so can lead to race conditions with the eventual call at the program's end.
|
||||
// As alternatives, the [Quit] or [Kill] convenience methods should be used instead.
|
||||
func (p *Program) shutdown(kill bool) {
|
||||
p.cancel()
|
||||
|
||||
@ -744,19 +796,30 @@ func (p *Program) shutdown(kill bool) {
|
||||
}
|
||||
|
||||
_ = p.restoreTerminalState()
|
||||
if !kill {
|
||||
p.finished <- struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// recoverFromPanic recovers from a panic, prints the stack trace, and restores
|
||||
// the terminal to a usable state.
|
||||
func (p *Program) recoverFromPanic() {
|
||||
if r := recover(); r != nil {
|
||||
p.shutdown(true)
|
||||
fmt.Printf("Caught panic:\n\n%s\n\nRestoring terminal...\n\n", r)
|
||||
debug.PrintStack()
|
||||
func (p *Program) recoverFromPanic(r interface{}) {
|
||||
select {
|
||||
case p.errs <- ErrProgramPanic:
|
||||
default:
|
||||
}
|
||||
p.shutdown(true) // Ok to call here, p.Run() cannot do it anymore.
|
||||
fmt.Printf("Caught panic:\n\n%s\n\nRestoring terminal...\n\n", r)
|
||||
debug.PrintStack()
|
||||
}
|
||||
|
||||
// recoverFromGoPanic recovers from a goroutine panic, prints a stack trace and
|
||||
// signals for the program to be killed and terminal restored to a usable state.
|
||||
func (p *Program) recoverFromGoPanic(r interface{}) {
|
||||
select {
|
||||
case p.errs <- ErrProgramPanic:
|
||||
default:
|
||||
}
|
||||
p.cancel()
|
||||
fmt.Printf("Caught goroutine panic:\n\n%s\n\nRestoring terminal...\n\n", r)
|
||||
debug.PrintStack()
|
||||
}
|
||||
|
||||
// ReleaseTerminal restores the original terminal state and cancels the input
|
||||
|
4
vendor/github.com/charmbracelet/bubbletea/tty.go
generated
vendored
4
vendor/github.com/charmbracelet/bubbletea/tty.go
generated
vendored
@ -52,7 +52,7 @@ func (p *Program) restoreTerminalState() error {
|
||||
p.renderer.exitAltScreen()
|
||||
|
||||
// give the terminal a moment to catch up
|
||||
time.Sleep(time.Millisecond * 10) //nolint:gomnd
|
||||
time.Sleep(time.Millisecond * 10) //nolint:mnd
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ func (p *Program) readLoop() {
|
||||
func (p *Program) waitForReadLoop() {
|
||||
select {
|
||||
case <-p.readLoopDone:
|
||||
case <-time.After(500 * time.Millisecond): //nolint:gomnd
|
||||
case <-time.After(500 * time.Millisecond): //nolint:mnd
|
||||
// The read loop hangs, which means the input
|
||||
// cancelReader's cancel function has returned true even
|
||||
// though it was not able to cancel the read.
|
||||
|
8
vendor/github.com/charmbracelet/bubbletea/tty_windows.go
generated
vendored
8
vendor/github.com/charmbracelet/bubbletea/tty_windows.go
generated
vendored
@ -19,7 +19,7 @@ func (p *Program) initInput() (err error) {
|
||||
p.ttyInput = f
|
||||
p.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error making raw: %w", err)
|
||||
}
|
||||
|
||||
// Enable VT input
|
||||
@ -38,7 +38,7 @@ func (p *Program) initInput() (err error) {
|
||||
p.ttyOutput = f
|
||||
p.previousOutputState, err = term.GetState(f.Fd())
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error getting state: %w", err)
|
||||
}
|
||||
|
||||
var mode uint32
|
||||
@ -51,14 +51,14 @@ func (p *Program) initInput() (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Open the Windows equivalent of a TTY.
|
||||
func openInputTTY() (*os.File, error) {
|
||||
f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("error opening file: %w", err)
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
40
vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml
generated
vendored
40
vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml
generated
vendored
@ -1,40 +0,0 @@
|
||||
run:
|
||||
tests: false
|
||||
issues-exit-code: 0
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- exhaustive
|
||||
- goconst
|
||||
- godot
|
||||
- godox
|
||||
- mnd
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- wrapcheck
|
||||
|
||||
# disable default linters, they are already enabled in .golangci.yml
|
||||
disable:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unused
|
41
vendor/github.com/charmbracelet/colorprofile/.golangci.yml
generated
vendored
41
vendor/github.com/charmbracelet/colorprofile/.golangci.yml
generated
vendored
@ -1,24 +1,23 @@
|
||||
version: "2"
|
||||
run:
|
||||
tests: false
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- gofumpt
|
||||
- goimports
|
||||
- exhaustive
|
||||
- goconst
|
||||
- godot
|
||||
- godox
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
@ -26,3 +25,17 @@ linters:
|
||||
- unconvert
|
||||
- unparam
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- common-false-positives
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gofumpt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
|
4
vendor/github.com/charmbracelet/colorprofile/doc.go
generated
vendored
Normal file
4
vendor/github.com/charmbracelet/colorprofile/doc.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
// Package colorprofile provides a way to downsample ANSI escape sequence
|
||||
// colors and styles automatically based on output, environment variables, and
|
||||
// Terminfo databases.
|
||||
package colorprofile
|
36
vendor/github.com/charmbracelet/colorprofile/env.go
generated
vendored
36
vendor/github.com/charmbracelet/colorprofile/env.go
generated
vendored
@ -12,6 +12,8 @@ import (
|
||||
"github.com/xo/terminfo"
|
||||
)
|
||||
|
||||
const dumbTerm = "dumb"
|
||||
|
||||
// Detect returns the color profile based on the terminal output, and
|
||||
// environment variables. This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE
|
||||
// environment variables.
|
||||
@ -29,10 +31,10 @@ import (
|
||||
// See https://no-color.org/ and https://bixense.com/clicolors/ for more information.
|
||||
func Detect(output io.Writer, env []string) Profile {
|
||||
out, ok := output.(term.File)
|
||||
isatty := ok && term.IsTerminal(out.Fd())
|
||||
environ := newEnviron(env)
|
||||
term := environ.get("TERM")
|
||||
isDumb := term == "dumb"
|
||||
isatty := isTTYForced(environ) || (ok && term.IsTerminal(out.Fd()))
|
||||
term, ok := environ.lookup("TERM")
|
||||
isDumb := !ok || term == dumbTerm
|
||||
envp := colorProfile(isatty, environ)
|
||||
if envp == TrueColor || envNoColor(environ) {
|
||||
// We already know we have TrueColor, or NO_COLOR is set.
|
||||
@ -69,7 +71,8 @@ func Env(env []string) (p Profile) {
|
||||
}
|
||||
|
||||
func colorProfile(isatty bool, env environ) (p Profile) {
|
||||
isDumb := env.get("TERM") == "dumb"
|
||||
term, ok := env.lookup("TERM")
|
||||
isDumb := (!ok && runtime.GOOS != "windows") || term == dumbTerm
|
||||
envp := envColorProfile(env)
|
||||
if !isatty || isDumb {
|
||||
// Check if the output is a terminal.
|
||||
@ -83,7 +86,7 @@ func colorProfile(isatty bool, env environ) (p Profile) {
|
||||
if p > Ascii {
|
||||
p = Ascii
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
if cliColorForced(env) {
|
||||
@ -94,7 +97,7 @@ func colorProfile(isatty bool, env environ) (p Profile) {
|
||||
p = envp
|
||||
}
|
||||
|
||||
return
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
if cliColor(env) {
|
||||
@ -123,6 +126,11 @@ func cliColorForced(env environ) bool {
|
||||
return cliColorForce
|
||||
}
|
||||
|
||||
func isTTYForced(env environ) bool {
|
||||
skip, _ := strconv.ParseBool(env.get("TTY_FORCE"))
|
||||
return skip
|
||||
}
|
||||
|
||||
func colorTerm(env environ) bool {
|
||||
colorTerm := strings.ToLower(env.get("COLORTERM"))
|
||||
return colorTerm == "truecolor" || colorTerm == "24bit" ||
|
||||
@ -132,7 +140,7 @@ func colorTerm(env environ) bool {
|
||||
// envColorProfile returns infers the color profile from the environment.
|
||||
func envColorProfile(env environ) (p Profile) {
|
||||
term, ok := env.lookup("TERM")
|
||||
if !ok || len(term) == 0 || term == "dumb" {
|
||||
if !ok || len(term) == 0 || term == dumbTerm {
|
||||
p = NoTTY
|
||||
if runtime.GOOS == "windows" {
|
||||
// Use Windows API to detect color profile. Windows Terminal and
|
||||
@ -184,7 +192,12 @@ func envColorProfile(env environ) (p Profile) {
|
||||
p = ANSI256
|
||||
}
|
||||
|
||||
return
|
||||
// Direct color terminals support true colors.
|
||||
if strings.HasSuffix(term, "direct") {
|
||||
return TrueColor
|
||||
}
|
||||
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
// Terminfo returns the color profile based on the terminal's terminfo
|
||||
@ -278,10 +291,3 @@ func (e environ) get(key string) string {
|
||||
v, _ := e.lookup(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func max[T ~byte | ~int](a, b T) T {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
10
vendor/github.com/charmbracelet/colorprofile/profile.go
generated
vendored
10
vendor/github.com/charmbracelet/colorprofile/profile.go
generated
vendored
@ -12,15 +12,15 @@ import (
|
||||
type Profile byte
|
||||
|
||||
const (
|
||||
// NoTTY, not a terminal profile.
|
||||
// NoTTY is a profile with no terminal support.
|
||||
NoTTY Profile = iota
|
||||
// Ascii, uncolored profile.
|
||||
// Ascii is a profile with no color support.
|
||||
Ascii //nolint:revive
|
||||
// ANSI, 4-bit color profile.
|
||||
// ANSI is a profile with 16 colors (4-bit).
|
||||
ANSI
|
||||
// ANSI256, 8-bit color profile.
|
||||
// ANSI256 is a profile with 256 colors (8-bit).
|
||||
ANSI256
|
||||
// TrueColor, 24-bit color profile.
|
||||
// TrueColor is a profile with 16 million colors (24-bit).
|
||||
TrueColor
|
||||
)
|
||||
|
||||
|
13
vendor/github.com/charmbracelet/colorprofile/writer.go
generated
vendored
13
vendor/github.com/charmbracelet/colorprofile/writer.go
generated
vendored
@ -2,6 +2,7 @@ package colorprofile
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"strconv"
|
||||
@ -37,11 +38,13 @@ type Writer struct {
|
||||
func (w *Writer) Write(p []byte) (int, error) {
|
||||
switch w.Profile {
|
||||
case TrueColor:
|
||||
return w.Forward.Write(p)
|
||||
return w.Forward.Write(p) //nolint:wrapcheck
|
||||
case NoTTY:
|
||||
return io.WriteString(w.Forward, ansi.Strip(string(p)))
|
||||
default:
|
||||
return io.WriteString(w.Forward, ansi.Strip(string(p))) //nolint:wrapcheck
|
||||
case Ascii, ANSI, ANSI256:
|
||||
return w.downsample(p)
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid profile: %v", w.Profile)
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +66,7 @@ func (w *Writer) downsample(p []byte) (int, error) {
|
||||
default:
|
||||
// If we're not a style SGR sequence, just write the bytes.
|
||||
if n, err := buf.Write(seq); err != nil {
|
||||
return n, err
|
||||
return n, err //nolint:wrapcheck
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +74,7 @@ func (w *Writer) downsample(p []byte) (int, error) {
|
||||
state = newState
|
||||
}
|
||||
|
||||
return w.Forward.Write(buf.Bytes())
|
||||
return w.Forward.Write(buf.Bytes()) //nolint:wrapcheck
|
||||
}
|
||||
|
||||
// WriteString writes the given text to the underlying writer.
|
||||
|
28
vendor/github.com/charmbracelet/log/.golangci.yml
generated
vendored
28
vendor/github.com/charmbracelet/log/.golangci.yml
generated
vendored
@ -1,17 +1,6 @@
|
||||
version: "2"
|
||||
run:
|
||||
tests: false
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
@ -19,8 +8,6 @@ linters:
|
||||
- goconst
|
||||
- godot
|
||||
- godox
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
@ -39,3 +26,16 @@ linters:
|
||||
- unparam
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- common-false-positives
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gofumpt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
|
8
vendor/github.com/charmbracelet/log/json.go
generated
vendored
8
vendor/github.com/charmbracelet/log/json.go
generated
vendored
@ -88,7 +88,13 @@ func (l *Logger) writeSlogValue(jw *jsonWriter, v slogValue) {
|
||||
}
|
||||
jw.end()
|
||||
default:
|
||||
jw.objectValue(v.Any())
|
||||
a := v.Any()
|
||||
_, jm := a.(json.Marshaler)
|
||||
if err, ok := a.(error); ok && !jm {
|
||||
jw.objectValue(err.Error())
|
||||
} else {
|
||||
jw.objectValue(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/charmbracelet/log/logger_121.go
generated
vendored
2
vendor/github.com/charmbracelet/log/logger_121.go
generated
vendored
@ -17,6 +17,8 @@ type (
|
||||
slogLogValuer = slog.LogValuer
|
||||
)
|
||||
|
||||
var slogAnyValue = slog.AnyValue
|
||||
|
||||
const slogKindGroup = slog.KindGroup
|
||||
|
||||
// Enabled reports whether the logger is enabled for the given level.
|
||||
|
2
vendor/github.com/charmbracelet/log/logger_no121.go
generated
vendored
2
vendor/github.com/charmbracelet/log/logger_no121.go
generated
vendored
@ -18,6 +18,8 @@ type (
|
||||
slogLogValuer = slog.LogValuer
|
||||
)
|
||||
|
||||
var slogAnyValue = slog.AnyValue
|
||||
|
||||
const slogKindGroup = slog.KindGroup
|
||||
|
||||
// Enabled reports whether the logger is enabled for the given level.
|
||||
|
2
vendor/github.com/charmbracelet/x/ansi/ansi.go
generated
vendored
2
vendor/github.com/charmbracelet/x/ansi/ansi.go
generated
vendored
@ -7,5 +7,5 @@ import "io"
|
||||
//
|
||||
// This is a syntactic sugar over [io.WriteString].
|
||||
func Execute(w io.Writer, s string) (int, error) {
|
||||
return io.WriteString(w, s)
|
||||
return io.WriteString(w, s) //nolint:wrapcheck
|
||||
}
|
||||
|
129
vendor/github.com/charmbracelet/x/ansi/background.go
generated
vendored
129
vendor/github.com/charmbracelet/x/ansi/background.go
generated
vendored
@ -3,63 +3,93 @@ package ansi
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
// Colorizer is a [color.Color] interface that can be formatted as a string.
|
||||
type Colorizer interface {
|
||||
color.Color
|
||||
fmt.Stringer
|
||||
// HexColor is a [color.Color] that can be formatted as a hex string.
|
||||
type HexColor string
|
||||
|
||||
// RGBA returns the RGBA values of the color.
|
||||
func (h HexColor) RGBA() (r, g, b, a uint32) {
|
||||
hex := h.color()
|
||||
if hex == nil {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
return hex.RGBA()
|
||||
}
|
||||
|
||||
// HexColorizer is a [color.Color] that can be formatted as a hex string.
|
||||
type HexColorizer struct{ color.Color }
|
||||
|
||||
var _ Colorizer = HexColorizer{}
|
||||
// Hex returns the hex representation of the color. If the color is invalid, it
|
||||
// returns an empty string.
|
||||
func (h HexColor) Hex() string {
|
||||
hex := h.color()
|
||||
if hex == nil {
|
||||
return ""
|
||||
}
|
||||
return hex.Hex()
|
||||
}
|
||||
|
||||
// String returns the color as a hex string. If the color is nil, an empty
|
||||
// string is returned.
|
||||
func (h HexColorizer) String() string {
|
||||
if h.Color == nil {
|
||||
return ""
|
||||
}
|
||||
r, g, b, _ := h.RGBA()
|
||||
// Get the lower 8 bits
|
||||
r &= 0xff
|
||||
g &= 0xff
|
||||
b &= 0xff
|
||||
return fmt.Sprintf("#%02x%02x%02x", uint8(r), uint8(g), uint8(b)) //nolint:gosec
|
||||
func (h HexColor) String() string {
|
||||
return h.Hex()
|
||||
}
|
||||
|
||||
// XRGBColorizer is a [color.Color] that can be formatted as an XParseColor
|
||||
// color returns the underlying color of the HexColor.
|
||||
func (h HexColor) color() *colorful.Color {
|
||||
hex, err := colorful.Hex(string(h))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &hex
|
||||
}
|
||||
|
||||
// XRGBColor is a [color.Color] that can be formatted as an XParseColor
|
||||
// rgb: string.
|
||||
//
|
||||
// See: https://linux.die.net/man/3/xparsecolor
|
||||
type XRGBColorizer struct{ color.Color }
|
||||
type XRGBColor struct {
|
||||
color.Color
|
||||
}
|
||||
|
||||
var _ Colorizer = XRGBColorizer{}
|
||||
// RGBA returns the RGBA values of the color.
|
||||
func (x XRGBColor) RGBA() (r, g, b, a uint32) {
|
||||
if x.Color == nil {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
return x.Color.RGBA()
|
||||
}
|
||||
|
||||
// String returns the color as an XParseColor rgb: string. If the color is nil,
|
||||
// an empty string is returned.
|
||||
func (x XRGBColorizer) String() string {
|
||||
func (x XRGBColor) String() string {
|
||||
if x.Color == nil {
|
||||
return ""
|
||||
}
|
||||
r, g, b, _ := x.RGBA()
|
||||
r, g, b, _ := x.Color.RGBA()
|
||||
// Get the lower 8 bits
|
||||
return fmt.Sprintf("rgb:%04x/%04x/%04x", r, g, b)
|
||||
}
|
||||
|
||||
// XRGBAColorizer is a [color.Color] that can be formatted as an XParseColor
|
||||
// XRGBAColor is a [color.Color] that can be formatted as an XParseColor
|
||||
// rgba: string.
|
||||
//
|
||||
// See: https://linux.die.net/man/3/xparsecolor
|
||||
type XRGBAColorizer struct{ color.Color }
|
||||
type XRGBAColor struct {
|
||||
color.Color
|
||||
}
|
||||
|
||||
var _ Colorizer = XRGBAColorizer{}
|
||||
// RGBA returns the RGBA values of the color.
|
||||
func (x XRGBAColor) RGBA() (r, g, b, a uint32) {
|
||||
if x.Color == nil {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
return x.Color.RGBA()
|
||||
}
|
||||
|
||||
// String returns the color as an XParseColor rgba: string. If the color is nil,
|
||||
// an empty string is returned.
|
||||
func (x XRGBAColorizer) String() string {
|
||||
func (x XRGBAColor) String() string {
|
||||
if x.Color == nil {
|
||||
return ""
|
||||
}
|
||||
@ -74,19 +104,12 @@ func (x XRGBAColorizer) String() string {
|
||||
// OSC 10 ; color ST
|
||||
// OSC 10 ; color BEL
|
||||
//
|
||||
// Where color is the encoded color number.
|
||||
// Where color is the encoded color number. Most terminals support hex,
|
||||
// XParseColor rgb: and rgba: strings. You could use [HexColor], [XRGBColor],
|
||||
// or [XRGBAColor] to format the color.
|
||||
//
|
||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
|
||||
func SetForegroundColor(c color.Color) string {
|
||||
var s string
|
||||
switch c := c.(type) {
|
||||
case Colorizer:
|
||||
s = c.String()
|
||||
case fmt.Stringer:
|
||||
s = c.String()
|
||||
default:
|
||||
s = HexColorizer{c}.String()
|
||||
}
|
||||
func SetForegroundColor(s string) string {
|
||||
return "\x1b]10;" + s + "\x07"
|
||||
}
|
||||
|
||||
@ -108,19 +131,12 @@ const ResetForegroundColor = "\x1b]110\x07"
|
||||
// OSC 11 ; color ST
|
||||
// OSC 11 ; color BEL
|
||||
//
|
||||
// Where color is the encoded color number.
|
||||
// Where color is the encoded color number. Most terminals support hex,
|
||||
// XParseColor rgb: and rgba: strings. You could use [HexColor], [XRGBColor],
|
||||
// or [XRGBAColor] to format the color.
|
||||
//
|
||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
|
||||
func SetBackgroundColor(c color.Color) string {
|
||||
var s string
|
||||
switch c := c.(type) {
|
||||
case Colorizer:
|
||||
s = c.String()
|
||||
case fmt.Stringer:
|
||||
s = c.String()
|
||||
default:
|
||||
s = HexColorizer{c}.String()
|
||||
}
|
||||
func SetBackgroundColor(s string) string {
|
||||
return "\x1b]11;" + s + "\x07"
|
||||
}
|
||||
|
||||
@ -141,19 +157,12 @@ const ResetBackgroundColor = "\x1b]111\x07"
|
||||
// OSC 12 ; color ST
|
||||
// OSC 12 ; color BEL
|
||||
//
|
||||
// Where color is the encoded color number.
|
||||
// Where color is the encoded color number. Most terminals support hex,
|
||||
// XParseColor rgb: and rgba: strings. You could use [HexColor], [XRGBColor],
|
||||
// or [XRGBAColor] to format the color.
|
||||
//
|
||||
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
|
||||
func SetCursorColor(c color.Color) string {
|
||||
var s string
|
||||
switch c := c.(type) {
|
||||
case Colorizer:
|
||||
s = c.String()
|
||||
case fmt.Stringer:
|
||||
s = c.String()
|
||||
default:
|
||||
s = HexColorizer{c}.String()
|
||||
}
|
||||
func SetCursorColor(s string) string {
|
||||
return "\x1b]12;" + s + "\x07"
|
||||
}
|
||||
|
||||
|
10
vendor/github.com/charmbracelet/x/ansi/charset.go
generated
vendored
10
vendor/github.com/charmbracelet/x/ansi/charset.go
generated
vendored
@ -39,17 +39,17 @@ func SCS(gset byte, charset byte) string {
|
||||
return SelectCharacterSet(gset, charset)
|
||||
}
|
||||
|
||||
// Locking Shift 1 Right (LS1R) shifts G1 into GR character set.
|
||||
// LS1R (Locking Shift 1 Right) shifts G1 into GR character set.
|
||||
const LS1R = "\x1b~"
|
||||
|
||||
// Locking Shift 2 (LS2) shifts G2 into GL character set.
|
||||
// LS2 (Locking Shift 2) shifts G2 into GL character set.
|
||||
const LS2 = "\x1bn"
|
||||
|
||||
// Locking Shift 2 Right (LS2R) shifts G2 into GR character set.
|
||||
// LS2R (Locking Shift 2 Right) shifts G2 into GR character set.
|
||||
const LS2R = "\x1b}"
|
||||
|
||||
// Locking Shift 3 (LS3) shifts G3 into GL character set.
|
||||
// LS3 (Locking Shift 3) shifts G3 into GL character set.
|
||||
const LS3 = "\x1bo"
|
||||
|
||||
// Locking Shift 3 Right (LS3R) shifts G3 into GR character set.
|
||||
// LS3R (Locking Shift 3 Right) shifts G3 into GR character set.
|
||||
const LS3R = "\x1b|"
|
||||
|
728
vendor/github.com/charmbracelet/x/ansi/color.go
generated
vendored
728
vendor/github.com/charmbracelet/x/ansi/color.go
generated
vendored
@ -2,34 +2,9 @@ package ansi
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
)
|
||||
|
||||
// Technically speaking, the 16 basic ANSI colors are arbitrary and can be
|
||||
// customized at the terminal level. Given that, we're returning what we feel
|
||||
// are good defaults.
|
||||
//
|
||||
// This could also be a slice, but we use a map to make the mappings very
|
||||
// explicit.
|
||||
//
|
||||
// See: https://www.ditig.com/publications/256-colors-cheat-sheet
|
||||
var lowANSI = map[uint32]uint32{
|
||||
0: 0x000000, // black
|
||||
1: 0x800000, // red
|
||||
2: 0x008000, // green
|
||||
3: 0x808000, // yellow
|
||||
4: 0x000080, // blue
|
||||
5: 0x800080, // magenta
|
||||
6: 0x008080, // cyan
|
||||
7: 0xc0c0c0, // white
|
||||
8: 0x808080, // bright black
|
||||
9: 0xff0000, // bright red
|
||||
10: 0x00ff00, // bright green
|
||||
11: 0xffff00, // bright yellow
|
||||
12: 0x0000ff, // bright blue
|
||||
13: 0xff00ff, // bright magenta
|
||||
14: 0x00ffff, // bright cyan
|
||||
15: 0xffffff, // bright white
|
||||
}
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
// Color is a color that can be used in a terminal. ANSI (including
|
||||
// ANSI256) and 24-bit "true colors" fall under this category.
|
||||
@ -100,28 +75,33 @@ func (c BasicColor) RGBA() (uint32, uint32, uint32, uint32) {
|
||||
return 0, 0, 0, 0xffff
|
||||
}
|
||||
|
||||
r, g, b := ansiToRGB(ansi)
|
||||
return toRGBA(r, g, b)
|
||||
return ansiToRGB(byte(ansi)).RGBA()
|
||||
}
|
||||
|
||||
// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255.
|
||||
type ExtendedColor uint8
|
||||
// IndexedColor is an ANSI 256 (8-bit) color with a value from 0 to 255.
|
||||
type IndexedColor uint8
|
||||
|
||||
var _ Color = ExtendedColor(0)
|
||||
var _ Color = IndexedColor(0)
|
||||
|
||||
// RGBA returns the red, green, blue and alpha components of the color. It
|
||||
// satisfies the color.Color interface.
|
||||
func (c ExtendedColor) RGBA() (uint32, uint32, uint32, uint32) {
|
||||
r, g, b := ansiToRGB(uint32(c))
|
||||
return toRGBA(r, g, b)
|
||||
func (c IndexedColor) RGBA() (uint32, uint32, uint32, uint32) {
|
||||
return ansiToRGB(byte(c)).RGBA()
|
||||
}
|
||||
|
||||
// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255.
|
||||
//
|
||||
// Deprecated: use [IndexedColor] instead.
|
||||
type ExtendedColor = IndexedColor
|
||||
|
||||
// TrueColor is a 24-bit color that can be used in the terminal.
|
||||
// This can be used to represent RGB colors.
|
||||
//
|
||||
// For example, the color red can be represented as:
|
||||
//
|
||||
// TrueColor(0xff0000)
|
||||
//
|
||||
// Deprecated: use [RGBColor] instead.
|
||||
type TrueColor uint32
|
||||
|
||||
var _ Color = TrueColor(0)
|
||||
@ -133,44 +113,25 @@ func (c TrueColor) RGBA() (uint32, uint32, uint32, uint32) {
|
||||
return toRGBA(r, g, b)
|
||||
}
|
||||
|
||||
// RGBColor is a 24-bit color that can be used in the terminal.
|
||||
// This can be used to represent RGB colors.
|
||||
type RGBColor struct {
|
||||
R uint8
|
||||
G uint8
|
||||
B uint8
|
||||
}
|
||||
|
||||
// RGBA returns the red, green, blue and alpha components of the color. It
|
||||
// satisfies the color.Color interface.
|
||||
func (c RGBColor) RGBA() (uint32, uint32, uint32, uint32) {
|
||||
return toRGBA(uint32(c.R), uint32(c.G), uint32(c.B))
|
||||
}
|
||||
|
||||
// ansiToRGB converts an ANSI color to a 24-bit RGB color.
|
||||
//
|
||||
// r, g, b := ansiToRGB(57)
|
||||
func ansiToRGB(ansi uint32) (uint32, uint32, uint32) {
|
||||
// For out-of-range values return black.
|
||||
if ansi > 255 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
|
||||
// Low ANSI.
|
||||
if ansi < 16 {
|
||||
h, ok := lowANSI[ansi]
|
||||
if !ok {
|
||||
return 0, 0, 0
|
||||
}
|
||||
r, g, b := hexToRGB(h)
|
||||
return r, g, b
|
||||
}
|
||||
|
||||
// Grays.
|
||||
if ansi > 231 {
|
||||
s := (ansi-232)*10 + 8
|
||||
return s, s, s
|
||||
}
|
||||
|
||||
// ANSI256.
|
||||
n := ansi - 16
|
||||
b := n % 6
|
||||
g := (n - b) / 6 % 6
|
||||
r := (n - b - g*6) / 36 % 6
|
||||
for _, v := range []*uint32{&r, &g, &b} {
|
||||
if *v > 0 {
|
||||
c := *v*40 + 55
|
||||
*v = c
|
||||
}
|
||||
}
|
||||
|
||||
return r, g, b
|
||||
func ansiToRGB(ansi byte) color.Color {
|
||||
return ansiHex[ansi]
|
||||
}
|
||||
|
||||
// hexToRGB converts a number in hexadecimal format to red, green, and blue
|
||||
@ -194,3 +155,630 @@ func toRGBA(r, g, b uint32) (uint32, uint32, uint32, uint32) {
|
||||
b |= b << 8
|
||||
return r, g, b, 0xffff
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func distSq(r1, g1, b1, r2, g2, b2 int) int {
|
||||
return ((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2))
|
||||
}
|
||||
|
||||
func to6Cube[T int | float64](v T) int {
|
||||
if v < 48 {
|
||||
return 0
|
||||
}
|
||||
if v < 115 {
|
||||
return 1
|
||||
}
|
||||
return int((v - 35) / 40)
|
||||
}
|
||||
|
||||
// Convert256 converts a [color.Color], usually a 24-bit color, to xterm(1) 256
|
||||
// color palette.
|
||||
//
|
||||
// xterm provides a 6x6x6 color cube (16 - 231) and 24 greys (232 - 255). We
|
||||
// map our RGB color to the closest in the cube, also work out the closest
|
||||
// grey, and use the nearest of the two based on the lightness of the color.
|
||||
//
|
||||
// Note that the xterm has much lower resolution for darker colors (they are
|
||||
// not evenly spread out), so our 6 levels are not evenly spread: 0x0, 0x5f
|
||||
// (95), 0x87 (135), 0xaf (175), 0xd7 (215) and 0xff (255). Greys are more
|
||||
// evenly spread (8, 18, 28 ... 238).
|
||||
func Convert256(c color.Color) IndexedColor {
|
||||
// If the color is already an IndexedColor, return it.
|
||||
if i, ok := c.(IndexedColor); ok {
|
||||
return i
|
||||
}
|
||||
|
||||
// Note: this is mostly ported from tmux/colour.c.
|
||||
col, ok := colorful.MakeColor(c)
|
||||
if !ok {
|
||||
return IndexedColor(0)
|
||||
}
|
||||
|
||||
r := col.R * 255
|
||||
g := col.G * 255
|
||||
b := col.B * 255
|
||||
|
||||
q2c := [6]int{0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
|
||||
|
||||
// Map RGB to 6x6x6 cube.
|
||||
qr := to6Cube(r)
|
||||
cr := q2c[qr]
|
||||
qg := to6Cube(g)
|
||||
cg := q2c[qg]
|
||||
qb := to6Cube(b)
|
||||
cb := q2c[qb]
|
||||
|
||||
// If we have hit the color exactly, return early.
|
||||
ci := (36 * qr) + (6 * qg) + qb
|
||||
if cr == int(r) && cg == int(g) && cb == int(b) {
|
||||
return IndexedColor(16 + ci) //nolint:gosec
|
||||
}
|
||||
|
||||
// Work out the closest grey (average of RGB).
|
||||
greyAvg := int(r+g+b) / 3
|
||||
var greyIdx int
|
||||
if greyAvg > 238 {
|
||||
greyIdx = 23
|
||||
} else {
|
||||
greyIdx = (greyAvg - 3) / 10
|
||||
}
|
||||
grey := 8 + (10 * greyIdx)
|
||||
|
||||
// Return the one which is nearer to the original input rgb value
|
||||
// XXX: This is where it differs from tmux's implementation, we prefer the
|
||||
// closer color to the original in terms of light distances rather than the
|
||||
// cube distance.
|
||||
c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
|
||||
g2 := colorful.Color{R: float64(grey) / 255.0, G: float64(grey) / 255.0, B: float64(grey) / 255.0}
|
||||
colorDist := col.DistanceHSLuv(c2)
|
||||
grayDist := col.DistanceHSLuv(g2)
|
||||
|
||||
if colorDist <= grayDist {
|
||||
return IndexedColor(16 + ci) //nolint:gosec
|
||||
}
|
||||
return IndexedColor(232 + greyIdx) //nolint:gosec
|
||||
|
||||
// // Is grey or 6x6x6 color closest?
|
||||
// d := distSq(cr, cg, cb, int(r), int(g), int(b))
|
||||
// if distSq(grey, grey, grey, int(r), int(g), int(b)) < d {
|
||||
// return IndexedColor(232 + greyIdx) //nolint:gosec
|
||||
// }
|
||||
// return IndexedColor(16 + ci) //nolint:gosec
|
||||
}
|
||||
|
||||
// Convert16 converts a [color.Color] to a 16-color ANSI color. It will first
|
||||
// try to find a match in the 256 xterm(1) color palette, and then map that to
|
||||
// the 16-color ANSI palette.
|
||||
func Convert16(c color.Color) BasicColor {
|
||||
switch c := c.(type) {
|
||||
case BasicColor:
|
||||
// If the color is already a BasicColor, return it.
|
||||
return c
|
||||
case IndexedColor:
|
||||
// If the color is already an IndexedColor, return the corresponding
|
||||
// BasicColor.
|
||||
return ansi256To16[c]
|
||||
default:
|
||||
c256 := Convert256(c)
|
||||
return ansi256To16[c256]
|
||||
}
|
||||
}
|
||||
|
||||
// RGB values of ANSI colors (0-255).
|
||||
var ansiHex = [...]color.RGBA{
|
||||
0: {R: 0x00, G: 0x00, B: 0x00, A: 0xff}, // "#000000"
|
||||
1: {R: 0x80, G: 0x00, B: 0x00, A: 0xff}, // "#800000"
|
||||
2: {R: 0x00, G: 0x80, B: 0x00, A: 0xff}, // "#008000"
|
||||
3: {R: 0x80, G: 0x80, B: 0x00, A: 0xff}, // "#808000"
|
||||
4: {R: 0x00, G: 0x00, B: 0x80, A: 0xff}, // "#000080"
|
||||
5: {R: 0x80, G: 0x00, B: 0x80, A: 0xff}, // "#800080"
|
||||
6: {R: 0x00, G: 0x80, B: 0x80, A: 0xff}, // "#008080"
|
||||
7: {R: 0xc0, G: 0xc0, B: 0xc0, A: 0xff}, // "#c0c0c0"
|
||||
8: {R: 0x80, G: 0x80, B: 0x80, A: 0xff}, // "#808080"
|
||||
9: {R: 0xff, G: 0x00, B: 0x00, A: 0xff}, // "#ff0000"
|
||||
10: {R: 0x00, G: 0xff, B: 0x00, A: 0xff}, // "#00ff00"
|
||||
11: {R: 0xff, G: 0xff, B: 0x00, A: 0xff}, // "#ffff00"
|
||||
12: {R: 0x00, G: 0x00, B: 0xff, A: 0xff}, // "#0000ff"
|
||||
13: {R: 0xff, G: 0x00, B: 0xff, A: 0xff}, // "#ff00ff"
|
||||
14: {R: 0x00, G: 0xff, B: 0xff, A: 0xff}, // "#00ffff"
|
||||
15: {R: 0xff, G: 0xff, B: 0xff, A: 0xff}, // "#ffffff"
|
||||
16: {R: 0x00, G: 0x00, B: 0x00, A: 0xff}, // "#000000"
|
||||
17: {R: 0x00, G: 0x00, B: 0x5f, A: 0xff}, // "#00005f"
|
||||
18: {R: 0x00, G: 0x00, B: 0x87, A: 0xff}, // "#000087"
|
||||
19: {R: 0x00, G: 0x00, B: 0xaf, A: 0xff}, // "#0000af"
|
||||
20: {R: 0x00, G: 0x00, B: 0xd7, A: 0xff}, // "#0000d7"
|
||||
21: {R: 0x00, G: 0x00, B: 0xff, A: 0xff}, // "#0000ff"
|
||||
22: {R: 0x00, G: 0x5f, B: 0x00, A: 0xff}, // "#005f00"
|
||||
23: {R: 0x00, G: 0x5f, B: 0x5f, A: 0xff}, // "#005f5f"
|
||||
24: {R: 0x00, G: 0x5f, B: 0x87, A: 0xff}, // "#005f87"
|
||||
25: {R: 0x00, G: 0x5f, B: 0xaf, A: 0xff}, // "#005faf"
|
||||
26: {R: 0x00, G: 0x5f, B: 0xd7, A: 0xff}, // "#005fd7"
|
||||
27: {R: 0x00, G: 0x5f, B: 0xff, A: 0xff}, // "#005fff"
|
||||
28: {R: 0x00, G: 0x87, B: 0x00, A: 0xff}, // "#008700"
|
||||
29: {R: 0x00, G: 0x87, B: 0x5f, A: 0xff}, // "#00875f"
|
||||
30: {R: 0x00, G: 0x87, B: 0x87, A: 0xff}, // "#008787"
|
||||
31: {R: 0x00, G: 0x87, B: 0xaf, A: 0xff}, // "#0087af"
|
||||
32: {R: 0x00, G: 0x87, B: 0xd7, A: 0xff}, // "#0087d7"
|
||||
33: {R: 0x00, G: 0x87, B: 0xff, A: 0xff}, // "#0087ff"
|
||||
34: {R: 0x00, G: 0xaf, B: 0x00, A: 0xff}, // "#00af00"
|
||||
35: {R: 0x00, G: 0xaf, B: 0x5f, A: 0xff}, // "#00af5f"
|
||||
36: {R: 0x00, G: 0xaf, B: 0x87, A: 0xff}, // "#00af87"
|
||||
37: {R: 0x00, G: 0xaf, B: 0xaf, A: 0xff}, // "#00afaf"
|
||||
38: {R: 0x00, G: 0xaf, B: 0xd7, A: 0xff}, // "#00afd7"
|
||||
39: {R: 0x00, G: 0xaf, B: 0xff, A: 0xff}, // "#00afff"
|
||||
40: {R: 0x00, G: 0xd7, B: 0x00, A: 0xff}, // "#00d700"
|
||||
41: {R: 0x00, G: 0xd7, B: 0x5f, A: 0xff}, // "#00d75f"
|
||||
42: {R: 0x00, G: 0xd7, B: 0x87, A: 0xff}, // "#00d787"
|
||||
43: {R: 0x00, G: 0xd7, B: 0xaf, A: 0xff}, // "#00d7af"
|
||||
44: {R: 0x00, G: 0xd7, B: 0xd7, A: 0xff}, // "#00d7d7"
|
||||
45: {R: 0x00, G: 0xd7, B: 0xff, A: 0xff}, // "#00d7ff"
|
||||
46: {R: 0x00, G: 0xff, B: 0x00, A: 0xff}, // "#00ff00"
|
||||
47: {R: 0x00, G: 0xff, B: 0x5f, A: 0xff}, // "#00ff5f"
|
||||
48: {R: 0x00, G: 0xff, B: 0x87, A: 0xff}, // "#00ff87"
|
||||
49: {R: 0x00, G: 0xff, B: 0xaf, A: 0xff}, // "#00ffaf"
|
||||
50: {R: 0x00, G: 0xff, B: 0xd7, A: 0xff}, // "#00ffd7"
|
||||
51: {R: 0x00, G: 0xff, B: 0xff, A: 0xff}, // "#00ffff"
|
||||
52: {R: 0x5f, G: 0x00, B: 0x00, A: 0xff}, // "#5f0000"
|
||||
53: {R: 0x5f, G: 0x00, B: 0x5f, A: 0xff}, // "#5f005f"
|
||||
54: {R: 0x5f, G: 0x00, B: 0x87, A: 0xff}, // "#5f0087"
|
||||
55: {R: 0x5f, G: 0x00, B: 0xaf, A: 0xff}, // "#5f00af"
|
||||
56: {R: 0x5f, G: 0x00, B: 0xd7, A: 0xff}, // "#5f00d7"
|
||||
57: {R: 0x5f, G: 0x00, B: 0xff, A: 0xff}, // "#5f00ff"
|
||||
58: {R: 0x5f, G: 0x5f, B: 0x00, A: 0xff}, // "#5f5f00"
|
||||
59: {R: 0x5f, G: 0x5f, B: 0x5f, A: 0xff}, // "#5f5f5f"
|
||||
60: {R: 0x5f, G: 0x5f, B: 0x87, A: 0xff}, // "#5f5f87"
|
||||
61: {R: 0x5f, G: 0x5f, B: 0xaf, A: 0xff}, // "#5f5faf"
|
||||
62: {R: 0x5f, G: 0x5f, B: 0xd7, A: 0xff}, // "#5f5fd7"
|
||||
63: {R: 0x5f, G: 0x5f, B: 0xff, A: 0xff}, // "#5f5fff"
|
||||
64: {R: 0x5f, G: 0x87, B: 0x00, A: 0xff}, // "#5f8700"
|
||||
65: {R: 0x5f, G: 0x87, B: 0x5f, A: 0xff}, // "#5f875f"
|
||||
66: {R: 0x5f, G: 0x87, B: 0x87, A: 0xff}, // "#5f8787"
|
||||
67: {R: 0x5f, G: 0x87, B: 0xaf, A: 0xff}, // "#5f87af"
|
||||
68: {R: 0x5f, G: 0x87, B: 0xd7, A: 0xff}, // "#5f87d7"
|
||||
69: {R: 0x5f, G: 0x87, B: 0xff, A: 0xff}, // "#5f87ff"
|
||||
70: {R: 0x5f, G: 0xaf, B: 0x00, A: 0xff}, // "#5faf00"
|
||||
71: {R: 0x5f, G: 0xaf, B: 0x5f, A: 0xff}, // "#5faf5f"
|
||||
72: {R: 0x5f, G: 0xaf, B: 0x87, A: 0xff}, // "#5faf87"
|
||||
73: {R: 0x5f, G: 0xaf, B: 0xaf, A: 0xff}, // "#5fafaf"
|
||||
74: {R: 0x5f, G: 0xaf, B: 0xd7, A: 0xff}, // "#5fafd7"
|
||||
75: {R: 0x5f, G: 0xaf, B: 0xff, A: 0xff}, // "#5fafff"
|
||||
76: {R: 0x5f, G: 0xd7, B: 0x00, A: 0xff}, // "#5fd700"
|
||||
77: {R: 0x5f, G: 0xd7, B: 0x5f, A: 0xff}, // "#5fd75f"
|
||||
78: {R: 0x5f, G: 0xd7, B: 0x87, A: 0xff}, // "#5fd787"
|
||||
79: {R: 0x5f, G: 0xd7, B: 0xaf, A: 0xff}, // "#5fd7af"
|
||||
80: {R: 0x5f, G: 0xd7, B: 0xd7, A: 0xff}, // "#5fd7d7"
|
||||
81: {R: 0x5f, G: 0xd7, B: 0xff, A: 0xff}, // "#5fd7ff"
|
||||
82: {R: 0x5f, G: 0xff, B: 0x00, A: 0xff}, // "#5fff00"
|
||||
83: {R: 0x5f, G: 0xff, B: 0x5f, A: 0xff}, // "#5fff5f"
|
||||
84: {R: 0x5f, G: 0xff, B: 0x87, A: 0xff}, // "#5fff87"
|
||||
85: {R: 0x5f, G: 0xff, B: 0xaf, A: 0xff}, // "#5fffaf"
|
||||
86: {R: 0x5f, G: 0xff, B: 0xd7, A: 0xff}, // "#5fffd7"
|
||||
87: {R: 0x5f, G: 0xff, B: 0xff, A: 0xff}, // "#5fffff"
|
||||
88: {R: 0x87, G: 0x00, B: 0x00, A: 0xff}, // "#870000"
|
||||
89: {R: 0x87, G: 0x00, B: 0x5f, A: 0xff}, // "#87005f"
|
||||
90: {R: 0x87, G: 0x00, B: 0x87, A: 0xff}, // "#870087"
|
||||
91: {R: 0x87, G: 0x00, B: 0xaf, A: 0xff}, // "#8700af"
|
||||
92: {R: 0x87, G: 0x00, B: 0xd7, A: 0xff}, // "#8700d7"
|
||||
93: {R: 0x87, G: 0x00, B: 0xff, A: 0xff}, // "#8700ff"
|
||||
94: {R: 0x87, G: 0x5f, B: 0x00, A: 0xff}, // "#875f00"
|
||||
95: {R: 0x87, G: 0x5f, B: 0x5f, A: 0xff}, // "#875f5f"
|
||||
96: {R: 0x87, G: 0x5f, B: 0x87, A: 0xff}, // "#875f87"
|
||||
97: {R: 0x87, G: 0x5f, B: 0xaf, A: 0xff}, // "#875faf"
|
||||
98: {R: 0x87, G: 0x5f, B: 0xd7, A: 0xff}, // "#875fd7"
|
||||
99: {R: 0x87, G: 0x5f, B: 0xff, A: 0xff}, // "#875fff"
|
||||
100: {R: 0x87, G: 0x87, B: 0x00, A: 0xff}, // "#878700"
|
||||
101: {R: 0x87, G: 0x87, B: 0x5f, A: 0xff}, // "#87875f"
|
||||
102: {R: 0x87, G: 0x87, B: 0x87, A: 0xff}, // "#878787"
|
||||
103: {R: 0x87, G: 0x87, B: 0xaf, A: 0xff}, // "#8787af"
|
||||
104: {R: 0x87, G: 0x87, B: 0xd7, A: 0xff}, // "#8787d7"
|
||||
105: {R: 0x87, G: 0x87, B: 0xff, A: 0xff}, // "#8787ff"
|
||||
106: {R: 0x87, G: 0xaf, B: 0x00, A: 0xff}, // "#87af00"
|
||||
107: {R: 0x87, G: 0xaf, B: 0x5f, A: 0xff}, // "#87af5f"
|
||||
108: {R: 0x87, G: 0xaf, B: 0x87, A: 0xff}, // "#87af87"
|
||||
109: {R: 0x87, G: 0xaf, B: 0xaf, A: 0xff}, // "#87afaf"
|
||||
110: {R: 0x87, G: 0xaf, B: 0xd7, A: 0xff}, // "#87afd7"
|
||||
111: {R: 0x87, G: 0xaf, B: 0xff, A: 0xff}, // "#87afff"
|
||||
112: {R: 0x87, G: 0xd7, B: 0x00, A: 0xff}, // "#87d700"
|
||||
113: {R: 0x87, G: 0xd7, B: 0x5f, A: 0xff}, // "#87d75f"
|
||||
114: {R: 0x87, G: 0xd7, B: 0x87, A: 0xff}, // "#87d787"
|
||||
115: {R: 0x87, G: 0xd7, B: 0xaf, A: 0xff}, // "#87d7af"
|
||||
116: {R: 0x87, G: 0xd7, B: 0xd7, A: 0xff}, // "#87d7d7"
|
||||
117: {R: 0x87, G: 0xd7, B: 0xff, A: 0xff}, // "#87d7ff"
|
||||
118: {R: 0x87, G: 0xff, B: 0x00, A: 0xff}, // "#87ff00"
|
||||
119: {R: 0x87, G: 0xff, B: 0x5f, A: 0xff}, // "#87ff5f"
|
||||
120: {R: 0x87, G: 0xff, B: 0x87, A: 0xff}, // "#87ff87"
|
||||
121: {R: 0x87, G: 0xff, B: 0xaf, A: 0xff}, // "#87ffaf"
|
||||
122: {R: 0x87, G: 0xff, B: 0xd7, A: 0xff}, // "#87ffd7"
|
||||
123: {R: 0x87, G: 0xff, B: 0xff, A: 0xff}, // "#87ffff"
|
||||
124: {R: 0xaf, G: 0x00, B: 0x00, A: 0xff}, // "#af0000"
|
||||
125: {R: 0xaf, G: 0x00, B: 0x5f, A: 0xff}, // "#af005f"
|
||||
126: {R: 0xaf, G: 0x00, B: 0x87, A: 0xff}, // "#af0087"
|
||||
127: {R: 0xaf, G: 0x00, B: 0xaf, A: 0xff}, // "#af00af"
|
||||
128: {R: 0xaf, G: 0x00, B: 0xd7, A: 0xff}, // "#af00d7"
|
||||
129: {R: 0xaf, G: 0x00, B: 0xff, A: 0xff}, // "#af00ff"
|
||||
130: {R: 0xaf, G: 0x5f, B: 0x00, A: 0xff}, // "#af5f00"
|
||||
131: {R: 0xaf, G: 0x5f, B: 0x5f, A: 0xff}, // "#af5f5f"
|
||||
132: {R: 0xaf, G: 0x5f, B: 0x87, A: 0xff}, // "#af5f87"
|
||||
133: {R: 0xaf, G: 0x5f, B: 0xaf, A: 0xff}, // "#af5faf"
|
||||
134: {R: 0xaf, G: 0x5f, B: 0xd7, A: 0xff}, // "#af5fd7"
|
||||
135: {R: 0xaf, G: 0x5f, B: 0xff, A: 0xff}, // "#af5fff"
|
||||
136: {R: 0xaf, G: 0x87, B: 0x00, A: 0xff}, // "#af8700"
|
||||
137: {R: 0xaf, G: 0x87, B: 0x5f, A: 0xff}, // "#af875f"
|
||||
138: {R: 0xaf, G: 0x87, B: 0x87, A: 0xff}, // "#af8787"
|
||||
139: {R: 0xaf, G: 0x87, B: 0xaf, A: 0xff}, // "#af87af"
|
||||
140: {R: 0xaf, G: 0x87, B: 0xd7, A: 0xff}, // "#af87d7"
|
||||
141: {R: 0xaf, G: 0x87, B: 0xff, A: 0xff}, // "#af87ff"
|
||||
142: {R: 0xaf, G: 0xaf, B: 0x00, A: 0xff}, // "#afaf00"
|
||||
143: {R: 0xaf, G: 0xaf, B: 0x5f, A: 0xff}, // "#afaf5f"
|
||||
144: {R: 0xaf, G: 0xaf, B: 0x87, A: 0xff}, // "#afaf87"
|
||||
145: {R: 0xaf, G: 0xaf, B: 0xaf, A: 0xff}, // "#afafaf"
|
||||
146: {R: 0xaf, G: 0xaf, B: 0xd7, A: 0xff}, // "#afafd7"
|
||||
147: {R: 0xaf, G: 0xaf, B: 0xff, A: 0xff}, // "#afafff"
|
||||
148: {R: 0xaf, G: 0xd7, B: 0x00, A: 0xff}, // "#afd700"
|
||||
149: {R: 0xaf, G: 0xd7, B: 0x5f, A: 0xff}, // "#afd75f"
|
||||
150: {R: 0xaf, G: 0xd7, B: 0x87, A: 0xff}, // "#afd787"
|
||||
151: {R: 0xaf, G: 0xd7, B: 0xaf, A: 0xff}, // "#afd7af"
|
||||
152: {R: 0xaf, G: 0xd7, B: 0xd7, A: 0xff}, // "#afd7d7"
|
||||
153: {R: 0xaf, G: 0xd7, B: 0xff, A: 0xff}, // "#afd7ff"
|
||||
154: {R: 0xaf, G: 0xff, B: 0x00, A: 0xff}, // "#afff00"
|
||||
155: {R: 0xaf, G: 0xff, B: 0x5f, A: 0xff}, // "#afff5f"
|
||||
156: {R: 0xaf, G: 0xff, B: 0x87, A: 0xff}, // "#afff87"
|
||||
157: {R: 0xaf, G: 0xff, B: 0xaf, A: 0xff}, // "#afffaf"
|
||||
158: {R: 0xaf, G: 0xff, B: 0xd7, A: 0xff}, // "#afffd7"
|
||||
159: {R: 0xaf, G: 0xff, B: 0xff, A: 0xff}, // "#afffff"
|
||||
160: {R: 0xd7, G: 0x00, B: 0x00, A: 0xff}, // "#d70000"
|
||||
161: {R: 0xd7, G: 0x00, B: 0x5f, A: 0xff}, // "#d7005f"
|
||||
162: {R: 0xd7, G: 0x00, B: 0x87, A: 0xff}, // "#d70087"
|
||||
163: {R: 0xd7, G: 0x00, B: 0xaf, A: 0xff}, // "#d700af"
|
||||
164: {R: 0xd7, G: 0x00, B: 0xd7, A: 0xff}, // "#d700d7"
|
||||
165: {R: 0xd7, G: 0x00, B: 0xff, A: 0xff}, // "#d700ff"
|
||||
166: {R: 0xd7, G: 0x5f, B: 0x00, A: 0xff}, // "#d75f00"
|
||||
167: {R: 0xd7, G: 0x5f, B: 0x5f, A: 0xff}, // "#d75f5f"
|
||||
168: {R: 0xd7, G: 0x5f, B: 0x87, A: 0xff}, // "#d75f87"
|
||||
169: {R: 0xd7, G: 0x5f, B: 0xaf, A: 0xff}, // "#d75faf"
|
||||
170: {R: 0xd7, G: 0x5f, B: 0xd7, A: 0xff}, // "#d75fd7"
|
||||
171: {R: 0xd7, G: 0x5f, B: 0xff, A: 0xff}, // "#d75fff"
|
||||
172: {R: 0xd7, G: 0x87, B: 0x00, A: 0xff}, // "#d78700"
|
||||
173: {R: 0xd7, G: 0x87, B: 0x5f, A: 0xff}, // "#d7875f"
|
||||
174: {R: 0xd7, G: 0x87, B: 0x87, A: 0xff}, // "#d78787"
|
||||
175: {R: 0xd7, G: 0x87, B: 0xaf, A: 0xff}, // "#d787af"
|
||||
176: {R: 0xd7, G: 0x87, B: 0xd7, A: 0xff}, // "#d787d7"
|
||||
177: {R: 0xd7, G: 0x87, B: 0xff, A: 0xff}, // "#d787ff"
|
||||
178: {R: 0xd7, G: 0xaf, B: 0x00, A: 0xff}, // "#d7af00"
|
||||
179: {R: 0xd7, G: 0xaf, B: 0x5f, A: 0xff}, // "#d7af5f"
|
||||
180: {R: 0xd7, G: 0xaf, B: 0x87, A: 0xff}, // "#d7af87"
|
||||
181: {R: 0xd7, G: 0xaf, B: 0xaf, A: 0xff}, // "#d7afaf"
|
||||
182: {R: 0xd7, G: 0xaf, B: 0xd7, A: 0xff}, // "#d7afd7"
|
||||
183: {R: 0xd7, G: 0xaf, B: 0xff, A: 0xff}, // "#d7afff"
|
||||
184: {R: 0xd7, G: 0xd7, B: 0x00, A: 0xff}, // "#d7d700"
|
||||
185: {R: 0xd7, G: 0xd7, B: 0x5f, A: 0xff}, // "#d7d75f"
|
||||
186: {R: 0xd7, G: 0xd7, B: 0x87, A: 0xff}, // "#d7d787"
|
||||
187: {R: 0xd7, G: 0xd7, B: 0xaf, A: 0xff}, // "#d7d7af"
|
||||
188: {R: 0xd7, G: 0xd7, B: 0xd7, A: 0xff}, // "#d7d7d7"
|
||||
189: {R: 0xd7, G: 0xd7, B: 0xff, A: 0xff}, // "#d7d7ff"
|
||||
190: {R: 0xd7, G: 0xff, B: 0x00, A: 0xff}, // "#d7ff00"
|
||||
191: {R: 0xd7, G: 0xff, B: 0x5f, A: 0xff}, // "#d7ff5f"
|
||||
192: {R: 0xd7, G: 0xff, B: 0x87, A: 0xff}, // "#d7ff87"
|
||||
193: {R: 0xd7, G: 0xff, B: 0xaf, A: 0xff}, // "#d7ffaf"
|
||||
194: {R: 0xd7, G: 0xff, B: 0xd7, A: 0xff}, // "#d7ffd7"
|
||||
195: {R: 0xd7, G: 0xff, B: 0xff, A: 0xff}, // "#d7ffff"
|
||||
196: {R: 0xff, G: 0x00, B: 0x00, A: 0xff}, // "#ff0000"
|
||||
197: {R: 0xff, G: 0x00, B: 0x5f, A: 0xff}, // "#ff005f"
|
||||
198: {R: 0xff, G: 0x00, B: 0x87, A: 0xff}, // "#ff0087"
|
||||
199: {R: 0xff, G: 0x00, B: 0xaf, A: 0xff}, // "#ff00af"
|
||||
200: {R: 0xff, G: 0x00, B: 0xd7, A: 0xff}, // "#ff00d7"
|
||||
201: {R: 0xff, G: 0x00, B: 0xff, A: 0xff}, // "#ff00ff"
|
||||
202: {R: 0xff, G: 0x5f, B: 0x00, A: 0xff}, // "#ff5f00"
|
||||
203: {R: 0xff, G: 0x5f, B: 0x5f, A: 0xff}, // "#ff5f5f"
|
||||
204: {R: 0xff, G: 0x5f, B: 0x87, A: 0xff}, // "#ff5f87"
|
||||
205: {R: 0xff, G: 0x5f, B: 0xaf, A: 0xff}, // "#ff5faf"
|
||||
206: {R: 0xff, G: 0x5f, B: 0xd7, A: 0xff}, // "#ff5fd7"
|
||||
207: {R: 0xff, G: 0x5f, B: 0xff, A: 0xff}, // "#ff5fff"
|
||||
208: {R: 0xff, G: 0x87, B: 0x00, A: 0xff}, // "#ff8700"
|
||||
209: {R: 0xff, G: 0x87, B: 0x5f, A: 0xff}, // "#ff875f"
|
||||
210: {R: 0xff, G: 0x87, B: 0x87, A: 0xff}, // "#ff8787"
|
||||
211: {R: 0xff, G: 0x87, B: 0xaf, A: 0xff}, // "#ff87af"
|
||||
212: {R: 0xff, G: 0x87, B: 0xd7, A: 0xff}, // "#ff87d7"
|
||||
213: {R: 0xff, G: 0x87, B: 0xff, A: 0xff}, // "#ff87ff"
|
||||
214: {R: 0xff, G: 0xaf, B: 0x00, A: 0xff}, // "#ffaf00"
|
||||
215: {R: 0xff, G: 0xaf, B: 0x5f, A: 0xff}, // "#ffaf5f"
|
||||
216: {R: 0xff, G: 0xaf, B: 0x87, A: 0xff}, // "#ffaf87"
|
||||
217: {R: 0xff, G: 0xaf, B: 0xaf, A: 0xff}, // "#ffafaf"
|
||||
218: {R: 0xff, G: 0xaf, B: 0xd7, A: 0xff}, // "#ffafd7"
|
||||
219: {R: 0xff, G: 0xaf, B: 0xff, A: 0xff}, // "#ffafff"
|
||||
220: {R: 0xff, G: 0xd7, B: 0x00, A: 0xff}, // "#ffd700"
|
||||
221: {R: 0xff, G: 0xd7, B: 0x5f, A: 0xff}, // "#ffd75f"
|
||||
222: {R: 0xff, G: 0xd7, B: 0x87, A: 0xff}, // "#ffd787"
|
||||
223: {R: 0xff, G: 0xd7, B: 0xaf, A: 0xff}, // "#ffd7af"
|
||||
224: {R: 0xff, G: 0xd7, B: 0xd7, A: 0xff}, // "#ffd7d7"
|
||||
225: {R: 0xff, G: 0xd7, B: 0xff, A: 0xff}, // "#ffd7ff"
|
||||
226: {R: 0xff, G: 0xff, B: 0x00, A: 0xff}, // "#ffff00"
|
||||
227: {R: 0xff, G: 0xff, B: 0x5f, A: 0xff}, // "#ffff5f"
|
||||
228: {R: 0xff, G: 0xff, B: 0x87, A: 0xff}, // "#ffff87"
|
||||
229: {R: 0xff, G: 0xff, B: 0xaf, A: 0xff}, // "#ffffaf"
|
||||
230: {R: 0xff, G: 0xff, B: 0xd7, A: 0xff}, // "#ffffd7"
|
||||
231: {R: 0xff, G: 0xff, B: 0xff, A: 0xff}, // "#ffffff"
|
||||
232: {R: 0x08, G: 0x08, B: 0x08, A: 0xff}, // "#080808"
|
||||
233: {R: 0x12, G: 0x12, B: 0x12, A: 0xff}, // "#121212"
|
||||
234: {R: 0x1c, G: 0x1c, B: 0x1c, A: 0xff}, // "#1c1c1c"
|
||||
235: {R: 0x26, G: 0x26, B: 0x26, A: 0xff}, // "#262626"
|
||||
236: {R: 0x30, G: 0x30, B: 0x30, A: 0xff}, // "#303030"
|
||||
237: {R: 0x3a, G: 0x3a, B: 0x3a, A: 0xff}, // "#3a3a3a"
|
||||
238: {R: 0x44, G: 0x44, B: 0x44, A: 0xff}, // "#444444"
|
||||
239: {R: 0x4e, G: 0x4e, B: 0x4e, A: 0xff}, // "#4e4e4e"
|
||||
240: {R: 0x58, G: 0x58, B: 0x58, A: 0xff}, // "#585858"
|
||||
241: {R: 0x62, G: 0x62, B: 0x62, A: 0xff}, // "#626262"
|
||||
242: {R: 0x6c, G: 0x6c, B: 0x6c, A: 0xff}, // "#6c6c6c"
|
||||
243: {R: 0x76, G: 0x76, B: 0x76, A: 0xff}, // "#767676"
|
||||
244: {R: 0x80, G: 0x80, B: 0x80, A: 0xff}, // "#808080"
|
||||
245: {R: 0x8a, G: 0x8a, B: 0x8a, A: 0xff}, // "#8a8a8a"
|
||||
246: {R: 0x94, G: 0x94, B: 0x94, A: 0xff}, // "#949494"
|
||||
247: {R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff}, // "#9e9e9e"
|
||||
248: {R: 0xa8, G: 0xa8, B: 0xa8, A: 0xff}, // "#a8a8a8"
|
||||
249: {R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff}, // "#b2b2b2"
|
||||
250: {R: 0xbc, G: 0xbc, B: 0xbc, A: 0xff}, // "#bcbcbc"
|
||||
251: {R: 0xc6, G: 0xc6, B: 0xc6, A: 0xff}, // "#c6c6c6"
|
||||
252: {R: 0xd0, G: 0xd0, B: 0xd0, A: 0xff}, // "#d0d0d0"
|
||||
253: {R: 0xda, G: 0xda, B: 0xda, A: 0xff}, // "#dadada"
|
||||
254: {R: 0xe4, G: 0xe4, B: 0xe4, A: 0xff}, // "#e4e4e4"
|
||||
255: {R: 0xee, G: 0xee, B: 0xee, A: 0xff}, // "#eeeeee"
|
||||
}
|
||||
|
||||
var ansi256To16 = [...]BasicColor{
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 3,
|
||||
4: 4,
|
||||
5: 5,
|
||||
6: 6,
|
||||
7: 7,
|
||||
8: 8,
|
||||
9: 9,
|
||||
10: 10,
|
||||
11: 11,
|
||||
12: 12,
|
||||
13: 13,
|
||||
14: 14,
|
||||
15: 15,
|
||||
16: 0,
|
||||
17: 4,
|
||||
18: 4,
|
||||
19: 4,
|
||||
20: 12,
|
||||
21: 12,
|
||||
22: 2,
|
||||
23: 6,
|
||||
24: 4,
|
||||
25: 4,
|
||||
26: 12,
|
||||
27: 12,
|
||||
28: 2,
|
||||
29: 2,
|
||||
30: 6,
|
||||
31: 4,
|
||||
32: 12,
|
||||
33: 12,
|
||||
34: 2,
|
||||
35: 2,
|
||||
36: 2,
|
||||
37: 6,
|
||||
38: 12,
|
||||
39: 12,
|
||||
40: 10,
|
||||
41: 10,
|
||||
42: 10,
|
||||
43: 10,
|
||||
44: 14,
|
||||
45: 12,
|
||||
46: 10,
|
||||
47: 10,
|
||||
48: 10,
|
||||
49: 10,
|
||||
50: 10,
|
||||
51: 14,
|
||||
52: 1,
|
||||
53: 5,
|
||||
54: 4,
|
||||
55: 4,
|
||||
56: 12,
|
||||
57: 12,
|
||||
58: 3,
|
||||
59: 8,
|
||||
60: 4,
|
||||
61: 4,
|
||||
62: 12,
|
||||
63: 12,
|
||||
64: 2,
|
||||
65: 2,
|
||||
66: 6,
|
||||
67: 4,
|
||||
68: 12,
|
||||
69: 12,
|
||||
70: 2,
|
||||
71: 2,
|
||||
72: 2,
|
||||
73: 6,
|
||||
74: 12,
|
||||
75: 12,
|
||||
76: 10,
|
||||
77: 10,
|
||||
78: 10,
|
||||
79: 10,
|
||||
80: 14,
|
||||
81: 12,
|
||||
82: 10,
|
||||
83: 10,
|
||||
84: 10,
|
||||
85: 10,
|
||||
86: 10,
|
||||
87: 14,
|
||||
88: 1,
|
||||
89: 1,
|
||||
90: 5,
|
||||
91: 4,
|
||||
92: 12,
|
||||
93: 12,
|
||||
94: 1,
|
||||
95: 1,
|
||||
96: 5,
|
||||
97: 4,
|
||||
98: 12,
|
||||
99: 12,
|
||||
100: 3,
|
||||
101: 3,
|
||||
102: 8,
|
||||
103: 4,
|
||||
104: 12,
|
||||
105: 12,
|
||||
106: 2,
|
||||
107: 2,
|
||||
108: 2,
|
||||
109: 6,
|
||||
110: 12,
|
||||
111: 12,
|
||||
112: 10,
|
||||
113: 10,
|
||||
114: 10,
|
||||
115: 10,
|
||||
116: 14,
|
||||
117: 12,
|
||||
118: 10,
|
||||
119: 10,
|
||||
120: 10,
|
||||
121: 10,
|
||||
122: 10,
|
||||
123: 14,
|
||||
124: 1,
|
||||
125: 1,
|
||||
126: 1,
|
||||
127: 5,
|
||||
128: 12,
|
||||
129: 12,
|
||||
130: 1,
|
||||
131: 1,
|
||||
132: 1,
|
||||
133: 5,
|
||||
134: 12,
|
||||
135: 12,
|
||||
136: 1,
|
||||
137: 1,
|
||||
138: 1,
|
||||
139: 5,
|
||||
140: 12,
|
||||
141: 12,
|
||||
142: 3,
|
||||
143: 3,
|
||||
144: 3,
|
||||
145: 7,
|
||||
146: 12,
|
||||
147: 12,
|
||||
148: 10,
|
||||
149: 10,
|
||||
150: 10,
|
||||
151: 10,
|
||||
152: 14,
|
||||
153: 12,
|
||||
154: 10,
|
||||
155: 10,
|
||||
156: 10,
|
||||
157: 10,
|
||||
158: 10,
|
||||
159: 14,
|
||||
160: 9,
|
||||
161: 9,
|
||||
162: 9,
|
||||
163: 9,
|
||||
164: 13,
|
||||
165: 12,
|
||||
166: 9,
|
||||
167: 9,
|
||||
168: 9,
|
||||
169: 9,
|
||||
170: 13,
|
||||
171: 12,
|
||||
172: 9,
|
||||
173: 9,
|
||||
174: 9,
|
||||
175: 9,
|
||||
176: 13,
|
||||
177: 12,
|
||||
178: 9,
|
||||
179: 9,
|
||||
180: 9,
|
||||
181: 9,
|
||||
182: 13,
|
||||
183: 12,
|
||||
184: 11,
|
||||
185: 11,
|
||||
186: 11,
|
||||
187: 11,
|
||||
188: 7,
|
||||
189: 12,
|
||||
190: 10,
|
||||
191: 10,
|
||||
192: 10,
|
||||
193: 10,
|
||||
194: 10,
|
||||
195: 14,
|
||||
196: 9,
|
||||
197: 9,
|
||||
198: 9,
|
||||
199: 9,
|
||||
200: 9,
|
||||
201: 13,
|
||||
202: 9,
|
||||
203: 9,
|
||||
204: 9,
|
||||
205: 9,
|
||||
206: 9,
|
||||
207: 13,
|
||||
208: 9,
|
||||
209: 9,
|
||||
210: 9,
|
||||
211: 9,
|
||||
212: 9,
|
||||
213: 13,
|
||||
214: 9,
|
||||
215: 9,
|
||||
216: 9,
|
||||
217: 9,
|
||||
218: 9,
|
||||
219: 13,
|
||||
220: 9,
|
||||
221: 9,
|
||||
222: 9,
|
||||
223: 9,
|
||||
224: 9,
|
||||
225: 13,
|
||||
226: 11,
|
||||
227: 11,
|
||||
228: 11,
|
||||
229: 11,
|
||||
230: 11,
|
||||
231: 15,
|
||||
232: 0,
|
||||
233: 0,
|
||||
234: 0,
|
||||
235: 0,
|
||||
236: 0,
|
||||
237: 0,
|
||||
238: 8,
|
||||
239: 8,
|
||||
240: 8,
|
||||
241: 8,
|
||||
242: 8,
|
||||
243: 8,
|
||||
244: 7,
|
||||
245: 7,
|
||||
246: 7,
|
||||
247: 7,
|
||||
248: 7,
|
||||
249: 7,
|
||||
250: 15,
|
||||
251: 15,
|
||||
252: 15,
|
||||
253: 15,
|
||||
254: 15,
|
||||
255: 15,
|
||||
}
|
||||
|
19
vendor/github.com/charmbracelet/x/ansi/ctrl.go
generated
vendored
19
vendor/github.com/charmbracelet/x/ansi/ctrl.go
generated
vendored
@ -38,6 +38,25 @@ const RequestXTVersion = RequestNameVersion
|
||||
// If no attributes are given, or if the attribute is 0, this function returns
|
||||
// the request sequence. Otherwise, it returns the response sequence.
|
||||
//
|
||||
// Common attributes include:
|
||||
// - 1 132 columns
|
||||
// - 2 Printer port
|
||||
// - 4 Sixel
|
||||
// - 6 Selective erase
|
||||
// - 7 Soft character set (DRCS)
|
||||
// - 8 User-defined keys (UDKs)
|
||||
// - 9 National replacement character sets (NRCS) (International terminal only)
|
||||
// - 12 Yugoslavian (SCS)
|
||||
// - 15 Technical character set
|
||||
// - 18 Windowing capability
|
||||
// - 21 Horizontal scrolling
|
||||
// - 23 Greek
|
||||
// - 24 Turkish
|
||||
// - 42 ISO Latin-2 character set
|
||||
// - 44 PCTerm
|
||||
// - 45 Soft key map
|
||||
// - 46 ASCII emulation
|
||||
//
|
||||
// See https://vt100.net/docs/vt510-rm/DA1.html
|
||||
func PrimaryDeviceAttributes(attrs ...int) string {
|
||||
if len(attrs) == 0 {
|
||||
|
12
vendor/github.com/charmbracelet/x/ansi/cursor.go
generated
vendored
12
vendor/github.com/charmbracelet/x/ansi/cursor.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package ansi
|
||||
|
||||
import "strconv"
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// SaveCursor (DECSC) is an escape sequence that saves the current cursor
|
||||
// position.
|
||||
@ -260,7 +262,7 @@ func CHA(col int) string {
|
||||
// See: https://vt100.net/docs/vt510-rm/CUP.html
|
||||
func CursorPosition(col, row int) string {
|
||||
if row <= 0 && col <= 0 {
|
||||
return HomeCursorPosition
|
||||
return CursorHomePosition
|
||||
}
|
||||
|
||||
var r, c string
|
||||
@ -356,8 +358,8 @@ func CHT(n int) string {
|
||||
return CursorHorizontalForwardTab(n)
|
||||
}
|
||||
|
||||
// EraseCharacter (ECH) returns a sequence for erasing n characters and moving
|
||||
// the cursor to the right. This doesn't affect other cell attributes.
|
||||
// EraseCharacter (ECH) returns a sequence for erasing n characters from the
|
||||
// screen. This doesn't affect other cell attributes.
|
||||
//
|
||||
// Default is 1.
|
||||
//
|
||||
@ -589,7 +591,7 @@ const ReverseIndex = "\x1bM"
|
||||
//
|
||||
// Default is 1.
|
||||
//
|
||||
// CSI n `
|
||||
// CSI n \`
|
||||
//
|
||||
// See: https://vt100.net/docs/vt510-rm/HPA.html
|
||||
func HorizontalPositionAbsolute(col int) string {
|
||||
|
67
vendor/github.com/charmbracelet/x/ansi/finalterm.go
generated
vendored
Normal file
67
vendor/github.com/charmbracelet/x/ansi/finalterm.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package ansi
|
||||
|
||||
import "strings"
|
||||
|
||||
// FinalTerm returns an escape sequence that is used for shell integrations.
|
||||
// Originally, FinalTerm designed the protocol hence the name.
|
||||
//
|
||||
// OSC 133 ; Ps ; Pm ST
|
||||
// OSC 133 ; Ps ; Pm BEL
|
||||
//
|
||||
// See: https://iterm2.com/documentation-shell-integration.html
|
||||
func FinalTerm(pm ...string) string {
|
||||
return "\x1b]133;" + strings.Join(pm, ";") + "\x07"
|
||||
}
|
||||
|
||||
// FinalTermPrompt returns an escape sequence that is used for shell
|
||||
// integrations prompt marks. This is sent just before the start of the shell
|
||||
// prompt.
|
||||
//
|
||||
// This is an alias for FinalTerm("A").
|
||||
func FinalTermPrompt(pm ...string) string {
|
||||
if len(pm) == 0 {
|
||||
return FinalTerm("A")
|
||||
}
|
||||
return FinalTerm(append([]string{"A"}, pm...)...)
|
||||
}
|
||||
|
||||
// FinalTermCmdStart returns an escape sequence that is used for shell
|
||||
// integrations command start marks. This is sent just after the end of the
|
||||
// shell prompt, before the user enters a command.
|
||||
//
|
||||
// This is an alias for FinalTerm("B").
|
||||
func FinalTermCmdStart(pm ...string) string {
|
||||
if len(pm) == 0 {
|
||||
return FinalTerm("B")
|
||||
}
|
||||
return FinalTerm(append([]string{"B"}, pm...)...)
|
||||
}
|
||||
|
||||
// FinalTermCmdExecuted returns an escape sequence that is used for shell
|
||||
// integrations command executed marks. This is sent just before the start of
|
||||
// the command output.
|
||||
//
|
||||
// This is an alias for FinalTerm("C").
|
||||
func FinalTermCmdExecuted(pm ...string) string {
|
||||
if len(pm) == 0 {
|
||||
return FinalTerm("C")
|
||||
}
|
||||
return FinalTerm(append([]string{"C"}, pm...)...)
|
||||
}
|
||||
|
||||
// FinalTermCmdFinished returns an escape sequence that is used for shell
|
||||
// integrations command finished marks.
|
||||
//
|
||||
// If the command was sent after
|
||||
// [FinalTermCmdStart], it indicates that the command was aborted. If the
|
||||
// command was sent after [FinalTermCmdExecuted], it indicates the end of the
|
||||
// command output. If neither was sent, [FinalTermCmdFinished] should be
|
||||
// ignored.
|
||||
//
|
||||
// This is an alias for FinalTerm("D").
|
||||
func FinalTermCmdFinished(pm ...string) string {
|
||||
if len(pm) == 0 {
|
||||
return FinalTerm("D")
|
||||
}
|
||||
return FinalTerm(append([]string{"D"}, pm...)...)
|
||||
}
|
213
vendor/github.com/charmbracelet/x/ansi/graphics.go
generated
vendored
213
vendor/github.com/charmbracelet/x/ansi/graphics.go
generated
vendored
@ -2,17 +2,47 @@ package ansi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/x/ansi/kitty"
|
||||
)
|
||||
|
||||
// SixelGraphics returns a sequence that encodes the given sixel image payload to
|
||||
// a DCS sixel sequence.
|
||||
//
|
||||
// DCS p1; p2; p3; q [sixel payload] ST
|
||||
//
|
||||
// p1 = pixel aspect ratio, deprecated and replaced by pixel metrics in the payload
|
||||
//
|
||||
// p2 = This is supposed to be 0 for transparency, but terminals don't seem to
|
||||
// to use it properly. Value 0 leaves an unsightly black bar on all terminals
|
||||
// I've tried and looks correct with value 1.
|
||||
//
|
||||
// p3 = Horizontal grid size parameter. Everyone ignores this and uses a fixed grid
|
||||
// size, as far as I can tell.
|
||||
//
|
||||
// See https://shuford.invisible-island.net/all_about_sixels.txt
|
||||
func SixelGraphics(p1, p2, p3 int, payload []byte) string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString("\x1bP")
|
||||
if p1 >= 0 {
|
||||
buf.WriteString(strconv.Itoa(p1))
|
||||
}
|
||||
buf.WriteByte(';')
|
||||
if p2 >= 0 {
|
||||
buf.WriteString(strconv.Itoa(p2))
|
||||
}
|
||||
if p3 > 0 {
|
||||
buf.WriteByte(';')
|
||||
buf.WriteString(strconv.Itoa(p3))
|
||||
}
|
||||
buf.WriteByte('q')
|
||||
buf.Write(payload)
|
||||
buf.WriteString("\x1b\\")
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// KittyGraphics returns a sequence that encodes the given image in the Kitty
|
||||
// graphics protocol.
|
||||
//
|
||||
@ -30,170 +60,3 @@ func KittyGraphics(payload []byte, opts ...string) string {
|
||||
buf.WriteString("\x1b\\")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var (
|
||||
// KittyGraphicsTempDir is the directory where temporary files are stored.
|
||||
// This is used in [WriteKittyGraphics] along with [os.CreateTemp].
|
||||
KittyGraphicsTempDir = ""
|
||||
|
||||
// KittyGraphicsTempPattern is the pattern used to create temporary files.
|
||||
// This is used in [WriteKittyGraphics] along with [os.CreateTemp].
|
||||
// The Kitty Graphics protocol requires the file path to contain the
|
||||
// substring "tty-graphics-protocol".
|
||||
KittyGraphicsTempPattern = "tty-graphics-protocol-*"
|
||||
)
|
||||
|
||||
// WriteKittyGraphics writes an image using the Kitty Graphics protocol with
|
||||
// the given options to w. It chunks the written data if o.Chunk is true.
|
||||
//
|
||||
// You can omit m and use nil when rendering an image from a file. In this
|
||||
// case, you must provide a file path in o.File and use o.Transmission =
|
||||
// [kitty.File]. You can also use o.Transmission = [kitty.TempFile] to write
|
||||
// the image to a temporary file. In that case, the file path is ignored, and
|
||||
// the image is written to a temporary file that is automatically deleted by
|
||||
// the terminal.
|
||||
//
|
||||
// See https://sw.kovidgoyal.net/kitty/graphics-protocol/
|
||||
func WriteKittyGraphics(w io.Writer, m image.Image, o *kitty.Options) error {
|
||||
if o == nil {
|
||||
o = &kitty.Options{}
|
||||
}
|
||||
|
||||
if o.Transmission == 0 && len(o.File) != 0 {
|
||||
o.Transmission = kitty.File
|
||||
}
|
||||
|
||||
var data bytes.Buffer // the data to be encoded into base64
|
||||
e := &kitty.Encoder{
|
||||
Compress: o.Compression == kitty.Zlib,
|
||||
Format: o.Format,
|
||||
}
|
||||
|
||||
switch o.Transmission {
|
||||
case kitty.Direct:
|
||||
if err := e.Encode(&data, m); err != nil {
|
||||
return fmt.Errorf("failed to encode direct image: %w", err)
|
||||
}
|
||||
|
||||
case kitty.SharedMemory:
|
||||
// TODO: Implement shared memory
|
||||
return fmt.Errorf("shared memory transmission is not yet implemented")
|
||||
|
||||
case kitty.File:
|
||||
if len(o.File) == 0 {
|
||||
return kitty.ErrMissingFile
|
||||
}
|
||||
|
||||
f, err := os.Open(o.File)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open file: %w", err)
|
||||
}
|
||||
|
||||
defer f.Close() //nolint:errcheck
|
||||
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get file info: %w", err)
|
||||
}
|
||||
|
||||
mode := stat.Mode()
|
||||
if !mode.IsRegular() {
|
||||
return fmt.Errorf("file is not a regular file")
|
||||
}
|
||||
|
||||
// Write the file path to the buffer
|
||||
if _, err := data.WriteString(f.Name()); err != nil {
|
||||
return fmt.Errorf("failed to write file path to buffer: %w", err)
|
||||
}
|
||||
|
||||
case kitty.TempFile:
|
||||
f, err := os.CreateTemp(KittyGraphicsTempDir, KittyGraphicsTempPattern)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
|
||||
defer f.Close() //nolint:errcheck
|
||||
|
||||
if err := e.Encode(f, m); err != nil {
|
||||
return fmt.Errorf("failed to encode image to file: %w", err)
|
||||
}
|
||||
|
||||
// Write the file path to the buffer
|
||||
if _, err := data.WriteString(f.Name()); err != nil {
|
||||
return fmt.Errorf("failed to write file path to buffer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Encode image to base64
|
||||
var payload bytes.Buffer // the base64 encoded image to be written to w
|
||||
b64 := base64.NewEncoder(base64.StdEncoding, &payload)
|
||||
if _, err := data.WriteTo(b64); err != nil {
|
||||
return fmt.Errorf("failed to write base64 encoded image to payload: %w", err)
|
||||
}
|
||||
if err := b64.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If not chunking, write all at once
|
||||
if !o.Chunk {
|
||||
_, err := io.WriteString(w, KittyGraphics(payload.Bytes(), o.Options()...))
|
||||
return err
|
||||
}
|
||||
|
||||
// Write in chunks
|
||||
var (
|
||||
err error
|
||||
n int
|
||||
)
|
||||
chunk := make([]byte, kitty.MaxChunkSize)
|
||||
isFirstChunk := true
|
||||
|
||||
for {
|
||||
// Stop if we read less than the chunk size [kitty.MaxChunkSize].
|
||||
n, err = io.ReadFull(&payload, chunk)
|
||||
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read chunk: %w", err)
|
||||
}
|
||||
|
||||
opts := buildChunkOptions(o, isFirstChunk, false)
|
||||
if _, err := io.WriteString(w, KittyGraphics(chunk[:n], opts...)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isFirstChunk = false
|
||||
}
|
||||
|
||||
// Write the last chunk
|
||||
opts := buildChunkOptions(o, isFirstChunk, true)
|
||||
_, err = io.WriteString(w, KittyGraphics(chunk[:n], opts...))
|
||||
return err
|
||||
}
|
||||
|
||||
// buildChunkOptions creates the options slice for a chunk
|
||||
func buildChunkOptions(o *kitty.Options, isFirstChunk, isLastChunk bool) []string {
|
||||
var opts []string
|
||||
if isFirstChunk {
|
||||
opts = o.Options()
|
||||
} else {
|
||||
// These options are allowed in subsequent chunks
|
||||
if o.Quite > 0 {
|
||||
opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
|
||||
}
|
||||
if o.Action == kitty.Frame {
|
||||
opts = append(opts, "a=f")
|
||||
}
|
||||
}
|
||||
|
||||
if !isFirstChunk || !isLastChunk {
|
||||
// We don't need to encode the (m=) option when we only have one chunk.
|
||||
if isLastChunk {
|
||||
opts = append(opts, "m=0")
|
||||
} else {
|
||||
opts = append(opts, "m=1")
|
||||
}
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
85
vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
generated
vendored
85
vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go
generated
vendored
@ -1,85 +0,0 @@
|
||||
package kitty
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Decoder is a decoder for the Kitty graphics protocol. It supports decoding
|
||||
// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats. It can also
|
||||
// decompress data using zlib.
|
||||
// The default format is 32-bit [RGBA].
|
||||
type Decoder struct {
|
||||
// Uses zlib decompression.
|
||||
Decompress bool
|
||||
|
||||
// Can be one of [RGB], [RGBA], or [PNG].
|
||||
Format int
|
||||
|
||||
// Width of the image in pixels. This can be omitted if the image is [PNG]
|
||||
// formatted.
|
||||
Width int
|
||||
|
||||
// Height of the image in pixels. This can be omitted if the image is [PNG]
|
||||
// formatted.
|
||||
Height int
|
||||
}
|
||||
|
||||
// Decode decodes the image data from r in the specified format.
|
||||
func (d *Decoder) Decode(r io.Reader) (image.Image, error) {
|
||||
if d.Decompress {
|
||||
zr, err := zlib.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create zlib reader: %w", err)
|
||||
}
|
||||
|
||||
defer zr.Close() //nolint:errcheck
|
||||
r = zr
|
||||
}
|
||||
|
||||
if d.Format == 0 {
|
||||
d.Format = RGBA
|
||||
}
|
||||
|
||||
switch d.Format {
|
||||
case RGBA, RGB:
|
||||
return d.decodeRGBA(r, d.Format == RGBA)
|
||||
|
||||
case PNG:
|
||||
return png.Decode(r)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported format: %d", d.Format)
|
||||
}
|
||||
}
|
||||
|
||||
// decodeRGBA decodes the image data in 32-bit RGBA or 24-bit RGB formats.
|
||||
func (d *Decoder) decodeRGBA(r io.Reader, alpha bool) (image.Image, error) {
|
||||
m := image.NewRGBA(image.Rect(0, 0, d.Width, d.Height))
|
||||
|
||||
var buf []byte
|
||||
if alpha {
|
||||
buf = make([]byte, 4)
|
||||
} else {
|
||||
buf = make([]byte, 3)
|
||||
}
|
||||
|
||||
for y := 0; y < d.Height; y++ {
|
||||
for x := 0; x < d.Width; x++ {
|
||||
if _, err := io.ReadFull(r, buf[:]); err != nil {
|
||||
return nil, fmt.Errorf("failed to read pixel data: %w", err)
|
||||
}
|
||||
if alpha {
|
||||
m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], buf[3]})
|
||||
} else {
|
||||
m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], 0xff})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
64
vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
generated
vendored
64
vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package kitty
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Encoder is an encoder for the Kitty graphics protocol. It supports encoding
|
||||
// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats, and
|
||||
// compressing the data using zlib.
|
||||
// The default format is 32-bit [RGBA].
|
||||
type Encoder struct {
|
||||
// Uses zlib compression.
|
||||
Compress bool
|
||||
|
||||
// Can be one of [RGBA], [RGB], or [PNG].
|
||||
Format int
|
||||
}
|
||||
|
||||
// Encode encodes the image data in the specified format and writes it to w.
|
||||
func (e *Encoder) Encode(w io.Writer, m image.Image) error {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if e.Compress {
|
||||
zw := zlib.NewWriter(w)
|
||||
defer zw.Close() //nolint:errcheck
|
||||
w = zw
|
||||
}
|
||||
|
||||
if e.Format == 0 {
|
||||
e.Format = RGBA
|
||||
}
|
||||
|
||||
switch e.Format {
|
||||
case RGBA, RGB:
|
||||
bounds := m.Bounds()
|
||||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||||
r, g, b, a := m.At(x, y).RGBA()
|
||||
switch e.Format {
|
||||
case RGBA:
|
||||
w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8), byte(a >> 8)}) //nolint:errcheck
|
||||
case RGB:
|
||||
w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8)}) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PNG:
|
||||
if err := png.Encode(w, m); err != nil {
|
||||
return fmt.Errorf("failed to encode PNG: %w", err)
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported format: %d", e.Format)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
414
vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
generated
vendored
414
vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go
generated
vendored
@ -1,414 +0,0 @@
|
||||
package kitty
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrMissingFile is returned when the file path is missing.
|
||||
var ErrMissingFile = errors.New("missing file path")
|
||||
|
||||
// MaxChunkSize is the maximum chunk size for the image data.
|
||||
const MaxChunkSize = 1024 * 4
|
||||
|
||||
// Placeholder is a special Unicode character that can be used as a placeholder
|
||||
// for an image.
|
||||
const Placeholder = '\U0010EEEE'
|
||||
|
||||
// Graphics image format.
|
||||
const (
|
||||
// 32-bit RGBA format.
|
||||
RGBA = 32
|
||||
|
||||
// 24-bit RGB format.
|
||||
RGB = 24
|
||||
|
||||
// PNG format.
|
||||
PNG = 100
|
||||
)
|
||||
|
||||
// Compression types.
|
||||
const (
|
||||
Zlib = 'z'
|
||||
)
|
||||
|
||||
// Transmission types.
|
||||
const (
|
||||
// The data transmitted directly in the escape sequence.
|
||||
Direct = 'd'
|
||||
|
||||
// The data transmitted in a regular file.
|
||||
File = 'f'
|
||||
|
||||
// A temporary file is used and deleted after transmission.
|
||||
TempFile = 't'
|
||||
|
||||
// A shared memory object.
|
||||
// For POSIX see https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html
|
||||
// For Windows see https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory
|
||||
SharedMemory = 's'
|
||||
)
|
||||
|
||||
// Action types.
|
||||
const (
|
||||
// Transmit image data.
|
||||
Transmit = 't'
|
||||
// TransmitAndPut transmit image data and display (put) it.
|
||||
TransmitAndPut = 'T'
|
||||
// Query terminal for image info.
|
||||
Query = 'q'
|
||||
// Put (display) previously transmitted image.
|
||||
Put = 'p'
|
||||
// Delete image.
|
||||
Delete = 'd'
|
||||
// Frame transmits data for animation frames.
|
||||
Frame = 'f'
|
||||
// Animate controls animation.
|
||||
Animate = 'a'
|
||||
// Compose composes animation frames.
|
||||
Compose = 'c'
|
||||
)
|
||||
|
||||
// Delete types.
|
||||
const (
|
||||
// Delete all placements visible on screen
|
||||
DeleteAll = 'a'
|
||||
// Delete all images with the specified id, specified using the i key. If
|
||||
// you specify a p key for the placement id as well, then only the
|
||||
// placement with the specified image id and placement id will be deleted.
|
||||
DeleteID = 'i'
|
||||
// Delete newest image with the specified number, specified using the I
|
||||
// key. If you specify a p key for the placement id as well, then only the
|
||||
// placement with the specified number and placement id will be deleted.
|
||||
DeleteNumber = 'n'
|
||||
// Delete all placements that intersect with the current cursor position.
|
||||
DeleteCursor = 'c'
|
||||
// Delete animation frames.
|
||||
DeleteFrames = 'f'
|
||||
// Delete all placements that intersect a specific cell, the cell is
|
||||
// specified using the x and y keys
|
||||
DeleteCell = 'p'
|
||||
// Delete all placements that intersect a specific cell having a specific
|
||||
// z-index. The cell and z-index is specified using the x, y and z keys.
|
||||
DeleteCellZ = 'q'
|
||||
// Delete all images whose id is greater than or equal to the value of the x
|
||||
// key and less than or equal to the value of the y.
|
||||
DeleteRange = 'r'
|
||||
// Delete all placements that intersect the specified column, specified using
|
||||
// the x key.
|
||||
DeleteColumn = 'x'
|
||||
// Delete all placements that intersect the specified row, specified using
|
||||
// the y key.
|
||||
DeleteRow = 'y'
|
||||
// Delete all placements that have the specified z-index, specified using the
|
||||
// z key.
|
||||
DeleteZ = 'z'
|
||||
)
|
||||
|
||||
// Diacritic returns the diacritic rune at the specified index. If the index is
|
||||
// out of bounds, the first diacritic rune is returned.
|
||||
func Diacritic(i int) rune {
|
||||
if i < 0 || i >= len(diacritics) {
|
||||
return diacritics[0]
|
||||
}
|
||||
return diacritics[i]
|
||||
}
|
||||
|
||||
// From https://sw.kovidgoyal.net/kitty/_downloads/f0a0de9ec8d9ff4456206db8e0814937/rowcolumn-diacritics.txt
|
||||
// See https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders for further explanation.
|
||||
var diacritics = []rune{
|
||||
'\u0305',
|
||||
'\u030D',
|
||||
'\u030E',
|
||||
'\u0310',
|
||||
'\u0312',
|
||||
'\u033D',
|
||||
'\u033E',
|
||||
'\u033F',
|
||||
'\u0346',
|
||||
'\u034A',
|
||||
'\u034B',
|
||||
'\u034C',
|
||||
'\u0350',
|
||||
'\u0351',
|
||||
'\u0352',
|
||||
'\u0357',
|
||||
'\u035B',
|
||||
'\u0363',
|
||||
'\u0364',
|
||||
'\u0365',
|
||||
'\u0366',
|
||||
'\u0367',
|
||||
'\u0368',
|
||||
'\u0369',
|
||||
'\u036A',
|
||||
'\u036B',
|
||||
'\u036C',
|
||||
'\u036D',
|
||||
'\u036E',
|
||||
'\u036F',
|
||||
'\u0483',
|
||||
'\u0484',
|
||||
'\u0485',
|
||||
'\u0486',
|
||||
'\u0487',
|
||||
'\u0592',
|
||||
'\u0593',
|
||||
'\u0594',
|
||||
'\u0595',
|
||||
'\u0597',
|
||||
'\u0598',
|
||||
'\u0599',
|
||||
'\u059C',
|
||||
'\u059D',
|
||||
'\u059E',
|
||||
'\u059F',
|
||||
'\u05A0',
|
||||
'\u05A1',
|
||||
'\u05A8',
|
||||
'\u05A9',
|
||||
'\u05AB',
|
||||
'\u05AC',
|
||||
'\u05AF',
|
||||
'\u05C4',
|
||||
'\u0610',
|
||||
'\u0611',
|
||||
'\u0612',
|
||||
'\u0613',
|
||||
'\u0614',
|
||||
'\u0615',
|
||||
'\u0616',
|
||||
'\u0617',
|
||||
'\u0657',
|
||||
'\u0658',
|
||||
'\u0659',
|
||||
'\u065A',
|
||||
'\u065B',
|
||||
'\u065D',
|
||||
'\u065E',
|
||||
'\u06D6',
|
||||
'\u06D7',
|
||||
'\u06D8',
|
||||
'\u06D9',
|
||||
'\u06DA',
|
||||
'\u06DB',
|
||||
'\u06DC',
|
||||
'\u06DF',
|
||||
'\u06E0',
|
||||
'\u06E1',
|
||||
'\u06E2',
|
||||
'\u06E4',
|
||||
'\u06E7',
|
||||
'\u06E8',
|
||||
'\u06EB',
|
||||
'\u06EC',
|
||||
'\u0730',
|
||||
'\u0732',
|
||||
'\u0733',
|
||||
'\u0735',
|
||||
'\u0736',
|
||||
'\u073A',
|
||||
'\u073D',
|
||||
'\u073F',
|
||||
'\u0740',
|
||||
'\u0741',
|
||||
'\u0743',
|
||||
'\u0745',
|
||||
'\u0747',
|
||||
'\u0749',
|
||||
'\u074A',
|
||||
'\u07EB',
|
||||
'\u07EC',
|
||||
'\u07ED',
|
||||
'\u07EE',
|
||||
'\u07EF',
|
||||
'\u07F0',
|
||||
'\u07F1',
|
||||
'\u07F3',
|
||||
'\u0816',
|
||||
'\u0817',
|
||||
'\u0818',
|
||||
'\u0819',
|
||||
'\u081B',
|
||||
'\u081C',
|
||||
'\u081D',
|
||||
'\u081E',
|
||||
'\u081F',
|
||||
'\u0820',
|
||||
'\u0821',
|
||||
'\u0822',
|
||||
'\u0823',
|
||||
'\u0825',
|
||||
'\u0826',
|
||||
'\u0827',
|
||||
'\u0829',
|
||||
'\u082A',
|
||||
'\u082B',
|
||||
'\u082C',
|
||||
'\u082D',
|
||||
'\u0951',
|
||||
'\u0953',
|
||||
'\u0954',
|
||||
'\u0F82',
|
||||
'\u0F83',
|
||||
'\u0F86',
|
||||
'\u0F87',
|
||||
'\u135D',
|
||||
'\u135E',
|
||||
'\u135F',
|
||||
'\u17DD',
|
||||
'\u193A',
|
||||
'\u1A17',
|
||||
'\u1A75',
|
||||
'\u1A76',
|
||||
'\u1A77',
|
||||
'\u1A78',
|
||||
'\u1A79',
|
||||
'\u1A7A',
|
||||
'\u1A7B',
|
||||
'\u1A7C',
|
||||
'\u1B6B',
|
||||
'\u1B6D',
|
||||
'\u1B6E',
|
||||
'\u1B6F',
|
||||
'\u1B70',
|
||||
'\u1B71',
|
||||
'\u1B72',
|
||||
'\u1B73',
|
||||
'\u1CD0',
|
||||
'\u1CD1',
|
||||
'\u1CD2',
|
||||
'\u1CDA',
|
||||
'\u1CDB',
|
||||
'\u1CE0',
|
||||
'\u1DC0',
|
||||
'\u1DC1',
|
||||
'\u1DC3',
|
||||
'\u1DC4',
|
||||
'\u1DC5',
|
||||
'\u1DC6',
|
||||
'\u1DC7',
|
||||
'\u1DC8',
|
||||
'\u1DC9',
|
||||
'\u1DCB',
|
||||
'\u1DCC',
|
||||
'\u1DD1',
|
||||
'\u1DD2',
|
||||
'\u1DD3',
|
||||
'\u1DD4',
|
||||
'\u1DD5',
|
||||
'\u1DD6',
|
||||
'\u1DD7',
|
||||
'\u1DD8',
|
||||
'\u1DD9',
|
||||
'\u1DDA',
|
||||
'\u1DDB',
|
||||
'\u1DDC',
|
||||
'\u1DDD',
|
||||
'\u1DDE',
|
||||
'\u1DDF',
|
||||
'\u1DE0',
|
||||
'\u1DE1',
|
||||
'\u1DE2',
|
||||
'\u1DE3',
|
||||
'\u1DE4',
|
||||
'\u1DE5',
|
||||
'\u1DE6',
|
||||
'\u1DFE',
|
||||
'\u20D0',
|
||||
'\u20D1',
|
||||
'\u20D4',
|
||||
'\u20D5',
|
||||
'\u20D6',
|
||||
'\u20D7',
|
||||
'\u20DB',
|
||||
'\u20DC',
|
||||
'\u20E1',
|
||||
'\u20E7',
|
||||
'\u20E9',
|
||||
'\u20F0',
|
||||
'\u2CEF',
|
||||
'\u2CF0',
|
||||
'\u2CF1',
|
||||
'\u2DE0',
|
||||
'\u2DE1',
|
||||
'\u2DE2',
|
||||
'\u2DE3',
|
||||
'\u2DE4',
|
||||
'\u2DE5',
|
||||
'\u2DE6',
|
||||
'\u2DE7',
|
||||
'\u2DE8',
|
||||
'\u2DE9',
|
||||
'\u2DEA',
|
||||
'\u2DEB',
|
||||
'\u2DEC',
|
||||
'\u2DED',
|
||||
'\u2DEE',
|
||||
'\u2DEF',
|
||||
'\u2DF0',
|
||||
'\u2DF1',
|
||||
'\u2DF2',
|
||||
'\u2DF3',
|
||||
'\u2DF4',
|
||||
'\u2DF5',
|
||||
'\u2DF6',
|
||||
'\u2DF7',
|
||||
'\u2DF8',
|
||||
'\u2DF9',
|
||||
'\u2DFA',
|
||||
'\u2DFB',
|
||||
'\u2DFC',
|
||||
'\u2DFD',
|
||||
'\u2DFE',
|
||||
'\u2DFF',
|
||||
'\uA66F',
|
||||
'\uA67C',
|
||||
'\uA67D',
|
||||
'\uA6F0',
|
||||
'\uA6F1',
|
||||
'\uA8E0',
|
||||
'\uA8E1',
|
||||
'\uA8E2',
|
||||
'\uA8E3',
|
||||
'\uA8E4',
|
||||
'\uA8E5',
|
||||
'\uA8E6',
|
||||
'\uA8E7',
|
||||
'\uA8E8',
|
||||
'\uA8E9',
|
||||
'\uA8EA',
|
||||
'\uA8EB',
|
||||
'\uA8EC',
|
||||
'\uA8ED',
|
||||
'\uA8EE',
|
||||
'\uA8EF',
|
||||
'\uA8F0',
|
||||
'\uA8F1',
|
||||
'\uAAB0',
|
||||
'\uAAB2',
|
||||
'\uAAB3',
|
||||
'\uAAB7',
|
||||
'\uAAB8',
|
||||
'\uAABE',
|
||||
'\uAABF',
|
||||
'\uAAC1',
|
||||
'\uFE20',
|
||||
'\uFE21',
|
||||
'\uFE22',
|
||||
'\uFE23',
|
||||
'\uFE24',
|
||||
'\uFE25',
|
||||
'\uFE26',
|
||||
'\U00010A0F',
|
||||
'\U00010A38',
|
||||
'\U0001D185',
|
||||
'\U0001D186',
|
||||
'\U0001D187',
|
||||
'\U0001D188',
|
||||
'\U0001D189',
|
||||
'\U0001D1AA',
|
||||
'\U0001D1AB',
|
||||
'\U0001D1AC',
|
||||
'\U0001D1AD',
|
||||
'\U0001D242',
|
||||
'\U0001D243',
|
||||
'\U0001D244',
|
||||
}
|
367
vendor/github.com/charmbracelet/x/ansi/kitty/options.go
generated
vendored
367
vendor/github.com/charmbracelet/x/ansi/kitty/options.go
generated
vendored
@ -1,367 +0,0 @@
|
||||
package kitty
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
_ encoding.TextMarshaler = Options{}
|
||||
_ encoding.TextUnmarshaler = &Options{}
|
||||
)
|
||||
|
||||
// Options represents a Kitty Graphics Protocol options.
|
||||
type Options struct {
|
||||
// Common options.
|
||||
|
||||
// Action (a=t) is the action to be performed on the image. Can be one of
|
||||
// [Transmit], [TransmitDisplay], [Query], [Put], [Delete], [Frame],
|
||||
// [Animate], [Compose].
|
||||
Action byte
|
||||
|
||||
// Quite mode (q=0) is the quiet mode. Can be either zero, one, or two
|
||||
// where zero is the default, 1 suppresses OK responses, and 2 suppresses
|
||||
// both OK and error responses.
|
||||
Quite byte
|
||||
|
||||
// Transmission options.
|
||||
|
||||
// ID (i=) is the image ID. The ID is a unique identifier for the image.
|
||||
// Must be a positive integer up to [math.MaxUint32].
|
||||
ID int
|
||||
|
||||
// PlacementID (p=) is the placement ID. The placement ID is a unique
|
||||
// identifier for the placement of the image. Must be a positive integer up
|
||||
// to [math.MaxUint32].
|
||||
PlacementID int
|
||||
|
||||
// Number (I=0) is the number of images to be transmitted.
|
||||
Number int
|
||||
|
||||
// Format (f=32) is the image format. One of [RGBA], [RGB], [PNG].
|
||||
Format int
|
||||
|
||||
// ImageWidth (s=0) is the transmitted image width.
|
||||
ImageWidth int
|
||||
|
||||
// ImageHeight (v=0) is the transmitted image height.
|
||||
ImageHeight int
|
||||
|
||||
// Compression (o=) is the image compression type. Can be [Zlib] or zero.
|
||||
Compression byte
|
||||
|
||||
// Transmission (t=d) is the image transmission type. Can be [Direct], [File],
|
||||
// [TempFile], or[SharedMemory].
|
||||
Transmission byte
|
||||
|
||||
// File is the file path to be used when the transmission type is [File].
|
||||
// If [Options.Transmission] is omitted i.e. zero and this is non-empty,
|
||||
// the transmission type is set to [File].
|
||||
File string
|
||||
|
||||
// Size (S=0) is the size to be read from the transmission medium.
|
||||
Size int
|
||||
|
||||
// Offset (O=0) is the offset byte to start reading from the transmission
|
||||
// medium.
|
||||
Offset int
|
||||
|
||||
// Chunk (m=) whether the image is transmitted in chunks. Can be either
|
||||
// zero or one. When true, the image is transmitted in chunks. Each chunk
|
||||
// must be a multiple of 4, and up to [MaxChunkSize] bytes. Each chunk must
|
||||
// have the m=1 option except for the last chunk which must have m=0.
|
||||
Chunk bool
|
||||
|
||||
// Display options.
|
||||
|
||||
// X (x=0) is the pixel X coordinate of the image to start displaying.
|
||||
X int
|
||||
|
||||
// Y (y=0) is the pixel Y coordinate of the image to start displaying.
|
||||
Y int
|
||||
|
||||
// Z (z=0) is the Z coordinate of the image to display.
|
||||
Z int
|
||||
|
||||
// Width (w=0) is the width of the image to display.
|
||||
Width int
|
||||
|
||||
// Height (h=0) is the height of the image to display.
|
||||
Height int
|
||||
|
||||
// OffsetX (X=0) is the OffsetX coordinate of the cursor cell to start
|
||||
// displaying the image. OffsetX=0 is the leftmost cell. This must be
|
||||
// smaller than the terminal cell width.
|
||||
OffsetX int
|
||||
|
||||
// OffsetY (Y=0) is the OffsetY coordinate of the cursor cell to start
|
||||
// displaying the image. OffsetY=0 is the topmost cell. This must be
|
||||
// smaller than the terminal cell height.
|
||||
OffsetY int
|
||||
|
||||
// Columns (c=0) is the number of columns to display the image. The image
|
||||
// will be scaled to fit the number of columns.
|
||||
Columns int
|
||||
|
||||
// Rows (r=0) is the number of rows to display the image. The image will be
|
||||
// scaled to fit the number of rows.
|
||||
Rows int
|
||||
|
||||
// VirtualPlacement (U=0) whether to use virtual placement. This is used
|
||||
// with Unicode [Placeholder] to display images.
|
||||
VirtualPlacement bool
|
||||
|
||||
// DoNotMoveCursor (C=0) whether to move the cursor after displaying the
|
||||
// image.
|
||||
DoNotMoveCursor bool
|
||||
|
||||
// ParentID (P=0) is the parent image ID. The parent ID is the ID of the
|
||||
// image that is the parent of the current image. This is used with Unicode
|
||||
// [Placeholder] to display images relative to the parent image.
|
||||
ParentID int
|
||||
|
||||
// ParentPlacementID (Q=0) is the parent placement ID. The parent placement
|
||||
// ID is the ID of the placement of the parent image. This is used with
|
||||
// Unicode [Placeholder] to display images relative to the parent image.
|
||||
ParentPlacementID int
|
||||
|
||||
// Delete options.
|
||||
|
||||
// Delete (d=a) is the delete action. Can be one of [DeleteAll],
|
||||
// [DeleteID], [DeleteNumber], [DeleteCursor], [DeleteFrames],
|
||||
// [DeleteCell], [DeleteCellZ], [DeleteRange], [DeleteColumn], [DeleteRow],
|
||||
// [DeleteZ].
|
||||
Delete byte
|
||||
|
||||
// DeleteResources indicates whether to delete the resources associated
|
||||
// with the image.
|
||||
DeleteResources bool
|
||||
}
|
||||
|
||||
// Options returns the options as a slice of a key-value pairs.
|
||||
func (o *Options) Options() (opts []string) {
|
||||
opts = []string{}
|
||||
if o.Format == 0 {
|
||||
o.Format = RGBA
|
||||
}
|
||||
|
||||
if o.Action == 0 {
|
||||
o.Action = Transmit
|
||||
}
|
||||
|
||||
if o.Delete == 0 {
|
||||
o.Delete = DeleteAll
|
||||
}
|
||||
|
||||
if o.Transmission == 0 {
|
||||
if len(o.File) > 0 {
|
||||
o.Transmission = File
|
||||
} else {
|
||||
o.Transmission = Direct
|
||||
}
|
||||
}
|
||||
|
||||
if o.Format != RGBA {
|
||||
opts = append(opts, fmt.Sprintf("f=%d", o.Format))
|
||||
}
|
||||
|
||||
if o.Quite > 0 {
|
||||
opts = append(opts, fmt.Sprintf("q=%d", o.Quite))
|
||||
}
|
||||
|
||||
if o.ID > 0 {
|
||||
opts = append(opts, fmt.Sprintf("i=%d", o.ID))
|
||||
}
|
||||
|
||||
if o.PlacementID > 0 {
|
||||
opts = append(opts, fmt.Sprintf("p=%d", o.PlacementID))
|
||||
}
|
||||
|
||||
if o.Number > 0 {
|
||||
opts = append(opts, fmt.Sprintf("I=%d", o.Number))
|
||||
}
|
||||
|
||||
if o.ImageWidth > 0 {
|
||||
opts = append(opts, fmt.Sprintf("s=%d", o.ImageWidth))
|
||||
}
|
||||
|
||||
if o.ImageHeight > 0 {
|
||||
opts = append(opts, fmt.Sprintf("v=%d", o.ImageHeight))
|
||||
}
|
||||
|
||||
if o.Transmission != Direct {
|
||||
opts = append(opts, fmt.Sprintf("t=%c", o.Transmission))
|
||||
}
|
||||
|
||||
if o.Size > 0 {
|
||||
opts = append(opts, fmt.Sprintf("S=%d", o.Size))
|
||||
}
|
||||
|
||||
if o.Offset > 0 {
|
||||
opts = append(opts, fmt.Sprintf("O=%d", o.Offset))
|
||||
}
|
||||
|
||||
if o.Compression == Zlib {
|
||||
opts = append(opts, fmt.Sprintf("o=%c", o.Compression))
|
||||
}
|
||||
|
||||
if o.VirtualPlacement {
|
||||
opts = append(opts, "U=1")
|
||||
}
|
||||
|
||||
if o.DoNotMoveCursor {
|
||||
opts = append(opts, "C=1")
|
||||
}
|
||||
|
||||
if o.ParentID > 0 {
|
||||
opts = append(opts, fmt.Sprintf("P=%d", o.ParentID))
|
||||
}
|
||||
|
||||
if o.ParentPlacementID > 0 {
|
||||
opts = append(opts, fmt.Sprintf("Q=%d", o.ParentPlacementID))
|
||||
}
|
||||
|
||||
if o.X > 0 {
|
||||
opts = append(opts, fmt.Sprintf("x=%d", o.X))
|
||||
}
|
||||
|
||||
if o.Y > 0 {
|
||||
opts = append(opts, fmt.Sprintf("y=%d", o.Y))
|
||||
}
|
||||
|
||||
if o.Z > 0 {
|
||||
opts = append(opts, fmt.Sprintf("z=%d", o.Z))
|
||||
}
|
||||
|
||||
if o.Width > 0 {
|
||||
opts = append(opts, fmt.Sprintf("w=%d", o.Width))
|
||||
}
|
||||
|
||||
if o.Height > 0 {
|
||||
opts = append(opts, fmt.Sprintf("h=%d", o.Height))
|
||||
}
|
||||
|
||||
if o.OffsetX > 0 {
|
||||
opts = append(opts, fmt.Sprintf("X=%d", o.OffsetX))
|
||||
}
|
||||
|
||||
if o.OffsetY > 0 {
|
||||
opts = append(opts, fmt.Sprintf("Y=%d", o.OffsetY))
|
||||
}
|
||||
|
||||
if o.Columns > 0 {
|
||||
opts = append(opts, fmt.Sprintf("c=%d", o.Columns))
|
||||
}
|
||||
|
||||
if o.Rows > 0 {
|
||||
opts = append(opts, fmt.Sprintf("r=%d", o.Rows))
|
||||
}
|
||||
|
||||
if o.Delete != DeleteAll || o.DeleteResources {
|
||||
da := o.Delete
|
||||
if o.DeleteResources {
|
||||
da = da - ' ' // to uppercase
|
||||
}
|
||||
|
||||
opts = append(opts, fmt.Sprintf("d=%c", da))
|
||||
}
|
||||
|
||||
if o.Action != Transmit {
|
||||
opts = append(opts, fmt.Sprintf("a=%c", o.Action))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// String returns the string representation of the options.
|
||||
func (o Options) String() string {
|
||||
return strings.Join(o.Options(), ",")
|
||||
}
|
||||
|
||||
// MarshalText returns the string representation of the options.
|
||||
func (o Options) MarshalText() ([]byte, error) {
|
||||
return []byte(o.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText parses the options from the given string.
|
||||
func (o *Options) UnmarshalText(text []byte) error {
|
||||
opts := strings.Split(string(text), ",")
|
||||
for _, opt := range opts {
|
||||
ps := strings.SplitN(opt, "=", 2)
|
||||
if len(ps) != 2 || len(ps[1]) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch ps[0] {
|
||||
case "a":
|
||||
o.Action = ps[1][0]
|
||||
case "o":
|
||||
o.Compression = ps[1][0]
|
||||
case "t":
|
||||
o.Transmission = ps[1][0]
|
||||
case "d":
|
||||
d := ps[1][0]
|
||||
if d >= 'A' && d <= 'Z' {
|
||||
o.DeleteResources = true
|
||||
d = d + ' ' // to lowercase
|
||||
}
|
||||
o.Delete = d
|
||||
case "i", "q", "p", "I", "f", "s", "v", "S", "O", "m", "x", "y", "z", "w", "h", "X", "Y", "c", "r", "U", "P", "Q":
|
||||
v, err := strconv.Atoi(ps[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch ps[0] {
|
||||
case "i":
|
||||
o.ID = v
|
||||
case "q":
|
||||
o.Quite = byte(v)
|
||||
case "p":
|
||||
o.PlacementID = v
|
||||
case "I":
|
||||
o.Number = v
|
||||
case "f":
|
||||
o.Format = v
|
||||
case "s":
|
||||
o.ImageWidth = v
|
||||
case "v":
|
||||
o.ImageHeight = v
|
||||
case "S":
|
||||
o.Size = v
|
||||
case "O":
|
||||
o.Offset = v
|
||||
case "m":
|
||||
o.Chunk = v == 0 || v == 1
|
||||
case "x":
|
||||
o.X = v
|
||||
case "y":
|
||||
o.Y = v
|
||||
case "z":
|
||||
o.Z = v
|
||||
case "w":
|
||||
o.Width = v
|
||||
case "h":
|
||||
o.Height = v
|
||||
case "X":
|
||||
o.OffsetX = v
|
||||
case "Y":
|
||||
o.OffsetY = v
|
||||
case "c":
|
||||
o.Columns = v
|
||||
case "r":
|
||||
o.Rows = v
|
||||
case "U":
|
||||
o.VirtualPlacement = v == 1
|
||||
case "P":
|
||||
o.ParentID = v
|
||||
case "Q":
|
||||
o.ParentPlacementID = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
106
vendor/github.com/charmbracelet/x/ansi/mode.go
generated
vendored
106
vendor/github.com/charmbracelet/x/ansi/mode.go
generated
vendored
@ -48,7 +48,7 @@ type Mode interface {
|
||||
Mode() int
|
||||
}
|
||||
|
||||
// SetMode (SM) returns a sequence to set a mode.
|
||||
// SetMode (SM) or (DECSET) returns a sequence to set a mode.
|
||||
// The mode arguments are a list of modes to set.
|
||||
//
|
||||
// If one of the modes is a [DECMode], the function will returns two escape
|
||||
@ -72,7 +72,12 @@ func SM(modes ...Mode) string {
|
||||
return SetMode(modes...)
|
||||
}
|
||||
|
||||
// ResetMode (RM) returns a sequence to reset a mode.
|
||||
// DECSET is an alias for [SetMode].
|
||||
func DECSET(modes ...Mode) string {
|
||||
return SetMode(modes...)
|
||||
}
|
||||
|
||||
// ResetMode (RM) or (DECRST) returns a sequence to reset a mode.
|
||||
// The mode arguments are a list of modes to reset.
|
||||
//
|
||||
// If one of the modes is a [DECMode], the function will returns two escape
|
||||
@ -96,9 +101,14 @@ func RM(modes ...Mode) string {
|
||||
return ResetMode(modes...)
|
||||
}
|
||||
|
||||
// DECRST is an alias for [ResetMode].
|
||||
func DECRST(modes ...Mode) string {
|
||||
return ResetMode(modes...)
|
||||
}
|
||||
|
||||
func setMode(reset bool, modes ...Mode) (s string) {
|
||||
if len(modes) == 0 {
|
||||
return
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
cmd := "h"
|
||||
@ -132,7 +142,7 @@ func setMode(reset bool, modes ...Mode) (s string) {
|
||||
if len(dec) > 0 {
|
||||
s += seq + "?" + strings.Join(dec, ";") + cmd
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
// RequestMode (DECRQM) returns a sequence to request a mode from the terminal.
|
||||
@ -243,6 +253,21 @@ const (
|
||||
RequestInsertReplaceMode = "\x1b[4$p"
|
||||
)
|
||||
|
||||
// BiDirectional Support Mode (BDSM) is a mode that determines whether the
|
||||
// terminal supports bidirectional text. When enabled, the terminal supports
|
||||
// bidirectional text and is set to implicit bidirectional mode. When disabled,
|
||||
// the terminal does not support bidirectional text.
|
||||
//
|
||||
// See ECMA-48 7.2.1.
|
||||
const (
|
||||
BiDirectionalSupportMode = ANSIMode(8)
|
||||
BDSM = BiDirectionalSupportMode
|
||||
|
||||
SetBiDirectionalSupportMode = "\x1b[8h"
|
||||
ResetBiDirectionalSupportMode = "\x1b[8l"
|
||||
RequestBiDirectionalSupportMode = "\x1b[8$p"
|
||||
)
|
||||
|
||||
// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether
|
||||
// the terminal echoes characters back to the host. When enabled, the terminal
|
||||
// sends characters to the host as they are typed.
|
||||
@ -297,7 +322,7 @@ const (
|
||||
|
||||
// Deprecated: use [SetCursorKeysMode] and [ResetCursorKeysMode] instead.
|
||||
const (
|
||||
EnableCursorKeys = "\x1b[?1h"
|
||||
EnableCursorKeys = "\x1b[?1h" //nolint:revive // grouped constants
|
||||
DisableCursorKeys = "\x1b[?1l"
|
||||
)
|
||||
|
||||
@ -548,8 +573,9 @@ const (
|
||||
|
||||
// Deprecated: use [SetFocusEventMode], [ResetFocusEventMode], and
|
||||
// [RequestFocusEventMode] instead.
|
||||
// Focus reporting mode constants.
|
||||
const (
|
||||
ReportFocusMode = DECMode(1004)
|
||||
ReportFocusMode = DECMode(1004) //nolint:revive // grouped constants
|
||||
|
||||
EnableReportFocus = "\x1b[?1004h"
|
||||
DisableReportFocus = "\x1b[?1004l"
|
||||
@ -577,7 +603,7 @@ const (
|
||||
// Deprecated: use [SgrExtMouseMode] [SetSgrExtMouseMode],
|
||||
// [ResetSgrExtMouseMode], and [RequestSgrExtMouseMode] instead.
|
||||
const (
|
||||
MouseSgrExtMode = DECMode(1006)
|
||||
MouseSgrExtMode = DECMode(1006) //nolint:revive // grouped constants
|
||||
EnableMouseSgrExt = "\x1b[?1006h"
|
||||
DisableMouseSgrExt = "\x1b[?1006l"
|
||||
RequestMouseSgrExt = "\x1b[?1006$p"
|
||||
@ -693,7 +719,7 @@ const (
|
||||
// Deprecated: use [SetBracketedPasteMode], [ResetBracketedPasteMode], and
|
||||
// [RequestBracketedPasteMode] instead.
|
||||
const (
|
||||
EnableBracketedPaste = "\x1b[?2004h"
|
||||
EnableBracketedPaste = "\x1b[?2004h" //nolint:revive // grouped constants
|
||||
DisableBracketedPaste = "\x1b[?2004l"
|
||||
RequestBracketedPaste = "\x1b[?2004$p"
|
||||
)
|
||||
@ -710,6 +736,8 @@ const (
|
||||
RequestSynchronizedOutputMode = "\x1b[?2026$p"
|
||||
)
|
||||
|
||||
// Synchronized Output Mode. See [SynchronizedOutputMode].
|
||||
//
|
||||
// Deprecated: use [SynchronizedOutputMode], [SetSynchronizedOutputMode], and
|
||||
// [ResetSynchronizedOutputMode], and [RequestSynchronizedOutputMode] instead.
|
||||
const (
|
||||
@ -720,12 +748,28 @@ const (
|
||||
RequestSyncdOutput = "\x1b[?2026$p"
|
||||
)
|
||||
|
||||
// Unicode Core Mode is a mode that determines whether the terminal should use
|
||||
// Unicode grapheme clustering to calculate the width of glyphs for each
|
||||
// terminal cell.
|
||||
//
|
||||
// See: https://github.com/contour-terminal/terminal-unicode-core
|
||||
const (
|
||||
UnicodeCoreMode = DECMode(2027)
|
||||
|
||||
SetUnicodeCoreMode = "\x1b[?2027h"
|
||||
ResetUnicodeCoreMode = "\x1b[?2027l"
|
||||
RequestUnicodeCoreMode = "\x1b[?2027$p"
|
||||
)
|
||||
|
||||
// Grapheme Clustering Mode is a mode that determines whether the terminal
|
||||
// should look for grapheme clusters instead of single runes in the rendered
|
||||
// text. This makes the terminal properly render combining characters such as
|
||||
// emojis.
|
||||
//
|
||||
// See: https://github.com/contour-terminal/terminal-unicode-core
|
||||
//
|
||||
// Deprecated: use [GraphemeClusteringMode], [SetUnicodeCoreMode],
|
||||
// [ResetUnicodeCoreMode], and [RequestUnicodeCoreMode] instead.
|
||||
const (
|
||||
GraphemeClusteringMode = DECMode(2027)
|
||||
|
||||
@ -734,14 +778,54 @@ const (
|
||||
RequestGraphemeClusteringMode = "\x1b[?2027$p"
|
||||
)
|
||||
|
||||
// Deprecated: use [SetGraphemeClusteringMode], [ResetGraphemeClusteringMode], and
|
||||
// [RequestGraphemeClusteringMode] instead.
|
||||
// Grapheme Clustering Mode. See [GraphemeClusteringMode].
|
||||
//
|
||||
// Deprecated: use [SetUnicodeCoreMode], [ResetUnicodeCoreMode], and
|
||||
// [RequestUnicodeCoreMode] instead.
|
||||
const (
|
||||
EnableGraphemeClustering = "\x1b[?2027h"
|
||||
DisableGraphemeClustering = "\x1b[?2027l"
|
||||
RequestGraphemeClustering = "\x1b[?2027$p"
|
||||
)
|
||||
|
||||
// LightDarkMode is a mode that enables reporting the operating system's color
|
||||
// scheme (light or dark) preference. It reports the color scheme as a [DSR]
|
||||
// and [LightDarkReport] escape sequences encoded as follows:
|
||||
//
|
||||
// CSI ? 997 ; 1 n for dark mode
|
||||
// CSI ? 997 ; 2 n for light mode
|
||||
//
|
||||
// The color preference can also be requested via the following [DSR] and
|
||||
// [RequestLightDarkReport] escape sequences:
|
||||
//
|
||||
// CSI ? 996 n
|
||||
//
|
||||
// See: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
|
||||
const (
|
||||
LightDarkMode = DECMode(2031)
|
||||
|
||||
SetLightDarkMode = "\x1b[?2031h"
|
||||
ResetLightDarkMode = "\x1b[?2031l"
|
||||
RequestLightDarkMode = "\x1b[?2031$p"
|
||||
)
|
||||
|
||||
// InBandResizeMode is a mode that reports terminal resize events as escape
|
||||
// sequences. This is useful for systems that do not support [SIGWINCH] like
|
||||
// Windows.
|
||||
//
|
||||
// The terminal then sends the following encoding:
|
||||
//
|
||||
// CSI 48 ; cellsHeight ; cellsWidth ; pixelHeight ; pixelWidth t
|
||||
//
|
||||
// See: https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
|
||||
const (
|
||||
InBandResizeMode = DECMode(2048)
|
||||
|
||||
SetInBandResizeMode = "\x1b[?2048h"
|
||||
ResetInBandResizeMode = "\x1b[?2048l"
|
||||
RequestInBandResizeMode = "\x1b[?2048$p"
|
||||
)
|
||||
|
||||
// Win32Input is a mode that determines whether input is processed by the
|
||||
// Win32 console and Conpty.
|
||||
//
|
||||
@ -757,7 +841,7 @@ const (
|
||||
// Deprecated: use [SetWin32InputMode], [ResetWin32InputMode], and
|
||||
// [RequestWin32InputMode] instead.
|
||||
const (
|
||||
EnableWin32Input = "\x1b[?9001h"
|
||||
EnableWin32Input = "\x1b[?9001h" //nolint:revive // grouped constants
|
||||
DisableWin32Input = "\x1b[?9001l"
|
||||
RequestWin32Input = "\x1b[?9001$p"
|
||||
)
|
||||
|
6
vendor/github.com/charmbracelet/x/ansi/modes.go
generated
vendored
6
vendor/github.com/charmbracelet/x/ansi/modes.go
generated
vendored
@ -4,12 +4,6 @@ package ansi
|
||||
// all modes are [ModeNotRecognized].
|
||||
type Modes map[Mode]ModeSetting
|
||||
|
||||
// NewModes creates a new Modes map. By default, all modes are
|
||||
// [ModeNotRecognized].
|
||||
func NewModes() Modes {
|
||||
return make(Modes)
|
||||
}
|
||||
|
||||
// Get returns the setting of a terminal mode. If the mode is not set, it
|
||||
// returns [ModeNotRecognized].
|
||||
func (m Modes) Get(mode Mode) ModeSetting {
|
||||
|
2
vendor/github.com/charmbracelet/x/ansi/mouse.go
generated
vendored
2
vendor/github.com/charmbracelet/x/ansi/mouse.go
generated
vendored
@ -134,7 +134,7 @@ func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
|
||||
m |= bitMotion
|
||||
}
|
||||
|
||||
return
|
||||
return //nolint:nakedret
|
||||
}
|
||||
|
||||
// x10Offset is the offset for X10 mouse events.
|
||||
|
4
vendor/github.com/charmbracelet/x/ansi/parser.go
generated
vendored
4
vendor/github.com/charmbracelet/x/ansi/parser.go
generated
vendored
@ -150,7 +150,7 @@ func (p *Parser) StateName() string {
|
||||
// Parse parses the given dispatcher and byte buffer.
|
||||
// Deprecated: Loop over the buffer and call [Parser.Advance] instead.
|
||||
func (p *Parser) Parse(b []byte) {
|
||||
for i := 0; i < len(b); i++ {
|
||||
for i := range b {
|
||||
p.Advance(b[i])
|
||||
}
|
||||
}
|
||||
@ -245,7 +245,7 @@ func (p *Parser) parseStringCmd() {
|
||||
if p.dataLen >= 0 {
|
||||
datalen = p.dataLen
|
||||
}
|
||||
for i := 0; i < datalen; i++ {
|
||||
for i := range datalen {
|
||||
d := p.data[i]
|
||||
if d < '0' || d > '9' {
|
||||
break
|
||||
|
5
vendor/github.com/charmbracelet/x/ansi/parser/const.go
generated
vendored
5
vendor/github.com/charmbracelet/x/ansi/parser/const.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
// Package parser provides ANSI escape sequence parsing functionality.
|
||||
package parser
|
||||
|
||||
// Action is a DEC ANSI parser action.
|
||||
@ -19,7 +20,7 @@ const (
|
||||
IgnoreAction = NoneAction
|
||||
)
|
||||
|
||||
// nolint: unused
|
||||
// ActionNames provides string names for parser actions.
|
||||
var ActionNames = []string{
|
||||
"NoneAction",
|
||||
"ClearAction",
|
||||
@ -58,7 +59,7 @@ const (
|
||||
Utf8State
|
||||
)
|
||||
|
||||
// nolint: unused
|
||||
// StateNames provides string names for parser states.
|
||||
var StateNames = []string{
|
||||
"GroundState",
|
||||
"CsiEntryState",
|
||||
|
6
vendor/github.com/charmbracelet/x/ansi/parser/seq.go
generated
vendored
6
vendor/github.com/charmbracelet/x/ansi/parser/seq.go
generated
vendored
@ -78,7 +78,7 @@ func Subparams(params []int, i int) []int {
|
||||
// Count the number of parameters before the given parameter index.
|
||||
var count int
|
||||
var j int
|
||||
for j = 0; j < len(params); j++ {
|
||||
for j = range params {
|
||||
if count == i {
|
||||
break
|
||||
}
|
||||
@ -116,7 +116,7 @@ func Subparams(params []int, i int) []int {
|
||||
// sub-parameters.
|
||||
func Len(params []int) int {
|
||||
var n int
|
||||
for i := 0; i < len(params); i++ {
|
||||
for i := range params {
|
||||
if !HasMore(params, i) {
|
||||
n++
|
||||
}
|
||||
@ -128,7 +128,7 @@ func Len(params []int) int {
|
||||
// function for each parameter.
|
||||
// The function should return false to stop the iteration.
|
||||
func Range(params []int, fn func(i int, param int, hasMore bool) bool) {
|
||||
for i := 0; i < len(params); i++ {
|
||||
for i := range params {
|
||||
if !fn(i, Param(params, i), HasMore(params, i)) {
|
||||
break
|
||||
}
|
||||
|
4
vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
generated
vendored
4
vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go
generated
vendored
@ -30,7 +30,7 @@ func NewTransitionTable(size int) TransitionTable {
|
||||
|
||||
// SetDefault sets default transition.
|
||||
func (t TransitionTable) SetDefault(action Action, state State) {
|
||||
for i := 0; i < len(t); i++ {
|
||||
for i := range t {
|
||||
t[i] = action<<TransitionActionShift | state
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ func (t TransitionTable) Transition(state State, code byte) (State, Action) {
|
||||
return value & TransitionStateMask, value >> TransitionActionShift
|
||||
}
|
||||
|
||||
// byte range macro
|
||||
// byte range macro.
|
||||
func r(start, end byte) []byte {
|
||||
var a []byte
|
||||
for i := int(start); i <= int(end); i++ {
|
||||
|
2
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
2
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
@ -359,7 +359,7 @@ func parseOscCmd(p *Parser) {
|
||||
if p == nil || p.cmd != parser.MissingCommand {
|
||||
return
|
||||
}
|
||||
for j := 0; j < p.dataLen; j++ {
|
||||
for j := range p.dataLen {
|
||||
d := p.data[j]
|
||||
if d < '0' || d > '9' {
|
||||
break
|
||||
|
7
vendor/github.com/charmbracelet/x/ansi/passthrough.go
generated
vendored
7
vendor/github.com/charmbracelet/x/ansi/passthrough.go
generated
vendored
@ -21,10 +21,7 @@ func ScreenPassthrough(seq string, limit int) string {
|
||||
b.WriteString("\x1bP")
|
||||
if limit > 0 {
|
||||
for i := 0; i < len(seq); i += limit {
|
||||
end := i + limit
|
||||
if end > len(seq) {
|
||||
end = len(seq)
|
||||
}
|
||||
end := min(i+limit, len(seq))
|
||||
b.WriteString(seq[i:end])
|
||||
if end < len(seq) {
|
||||
b.WriteString("\x1b\\\x1bP")
|
||||
@ -52,7 +49,7 @@ func ScreenPassthrough(seq string, limit int) string {
|
||||
func TmuxPassthrough(seq string) string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString("\x1bPtmux;")
|
||||
for i := 0; i < len(seq); i++ {
|
||||
for i := range len(seq) {
|
||||
if seq[i] == ESC {
|
||||
b.WriteByte(ESC)
|
||||
}
|
||||
|
6
vendor/github.com/charmbracelet/x/ansi/screen.go
generated
vendored
6
vendor/github.com/charmbracelet/x/ansi/screen.go
generated
vendored
@ -351,7 +351,7 @@ func DECRQPSR(n int) string {
|
||||
//
|
||||
// See: https://vt100.net/docs/vt510-rm/DECTABSR.html
|
||||
func TabStopReport(stops ...int) string {
|
||||
var s []string
|
||||
var s []string //nolint:prealloc
|
||||
for _, v := range stops {
|
||||
s = append(s, strconv.Itoa(v))
|
||||
}
|
||||
@ -376,7 +376,7 @@ func DECTABSR(stops ...int) string {
|
||||
//
|
||||
// See: https://vt100.net/docs/vt510-rm/DECCIR.html
|
||||
func CursorInformationReport(values ...int) string {
|
||||
var s []string
|
||||
var s []string //nolint:prealloc
|
||||
for _, v := range values {
|
||||
s = append(s, strconv.Itoa(v))
|
||||
}
|
||||
@ -395,7 +395,7 @@ func DECCIR(values ...int) string {
|
||||
//
|
||||
// CSI Pn b
|
||||
//
|
||||
// See: ECMA-48 § 8.3.103
|
||||
// See: ECMA-48 § 8.3.103.
|
||||
func RepeatPreviousCharacter(n int) string {
|
||||
var s string
|
||||
if n > 1 {
|
||||
|
130
vendor/github.com/charmbracelet/x/ansi/sgr.go
generated
vendored
130
vendor/github.com/charmbracelet/x/ansi/sgr.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package ansi
|
||||
|
||||
import "strconv"
|
||||
|
||||
// Select Graphic Rendition (SGR) is a command that sets display attributes.
|
||||
// SelectGraphicRendition (SGR) is a command that sets display attributes.
|
||||
//
|
||||
// Default is 0.
|
||||
//
|
||||
@ -14,20 +12,7 @@ func SelectGraphicRendition(ps ...Attr) string {
|
||||
return ResetStyle
|
||||
}
|
||||
|
||||
var s Style
|
||||
for _, p := range ps {
|
||||
attr, ok := attrStrings[p]
|
||||
if ok {
|
||||
s = append(s, attr)
|
||||
} else {
|
||||
if p < 0 {
|
||||
p = 0
|
||||
}
|
||||
s = append(s, strconv.Itoa(p))
|
||||
}
|
||||
}
|
||||
|
||||
return s.String()
|
||||
return NewStyle(ps...).String()
|
||||
}
|
||||
|
||||
// SGR is an alias for [SelectGraphicRendition].
|
||||
@ -36,60 +21,59 @@ func SGR(ps ...Attr) string {
|
||||
}
|
||||
|
||||
var attrStrings = map[int]string{
|
||||
ResetAttr: "0",
|
||||
BoldAttr: "1",
|
||||
FaintAttr: "2",
|
||||
ItalicAttr: "3",
|
||||
UnderlineAttr: "4",
|
||||
SlowBlinkAttr: "5",
|
||||
RapidBlinkAttr: "6",
|
||||
ReverseAttr: "7",
|
||||
ConcealAttr: "8",
|
||||
StrikethroughAttr: "9",
|
||||
NoBoldAttr: "21",
|
||||
NormalIntensityAttr: "22",
|
||||
NoItalicAttr: "23",
|
||||
NoUnderlineAttr: "24",
|
||||
NoBlinkAttr: "25",
|
||||
NoReverseAttr: "27",
|
||||
NoConcealAttr: "28",
|
||||
NoStrikethroughAttr: "29",
|
||||
BlackForegroundColorAttr: "30",
|
||||
RedForegroundColorAttr: "31",
|
||||
GreenForegroundColorAttr: "32",
|
||||
YellowForegroundColorAttr: "33",
|
||||
BlueForegroundColorAttr: "34",
|
||||
MagentaForegroundColorAttr: "35",
|
||||
CyanForegroundColorAttr: "36",
|
||||
WhiteForegroundColorAttr: "37",
|
||||
ExtendedForegroundColorAttr: "38",
|
||||
DefaultForegroundColorAttr: "39",
|
||||
BlackBackgroundColorAttr: "40",
|
||||
RedBackgroundColorAttr: "41",
|
||||
GreenBackgroundColorAttr: "42",
|
||||
YellowBackgroundColorAttr: "43",
|
||||
BlueBackgroundColorAttr: "44",
|
||||
MagentaBackgroundColorAttr: "45",
|
||||
CyanBackgroundColorAttr: "46",
|
||||
WhiteBackgroundColorAttr: "47",
|
||||
ExtendedBackgroundColorAttr: "48",
|
||||
DefaultBackgroundColorAttr: "49",
|
||||
ExtendedUnderlineColorAttr: "58",
|
||||
DefaultUnderlineColorAttr: "59",
|
||||
BrightBlackForegroundColorAttr: "90",
|
||||
BrightRedForegroundColorAttr: "91",
|
||||
BrightGreenForegroundColorAttr: "92",
|
||||
BrightYellowForegroundColorAttr: "93",
|
||||
BrightBlueForegroundColorAttr: "94",
|
||||
BrightMagentaForegroundColorAttr: "95",
|
||||
BrightCyanForegroundColorAttr: "96",
|
||||
BrightWhiteForegroundColorAttr: "97",
|
||||
BrightBlackBackgroundColorAttr: "100",
|
||||
BrightRedBackgroundColorAttr: "101",
|
||||
BrightGreenBackgroundColorAttr: "102",
|
||||
BrightYellowBackgroundColorAttr: "103",
|
||||
BrightBlueBackgroundColorAttr: "104",
|
||||
BrightMagentaBackgroundColorAttr: "105",
|
||||
BrightCyanBackgroundColorAttr: "106",
|
||||
BrightWhiteBackgroundColorAttr: "107",
|
||||
ResetAttr: resetAttr,
|
||||
BoldAttr: boldAttr,
|
||||
FaintAttr: faintAttr,
|
||||
ItalicAttr: italicAttr,
|
||||
UnderlineAttr: underlineAttr,
|
||||
SlowBlinkAttr: slowBlinkAttr,
|
||||
RapidBlinkAttr: rapidBlinkAttr,
|
||||
ReverseAttr: reverseAttr,
|
||||
ConcealAttr: concealAttr,
|
||||
StrikethroughAttr: strikethroughAttr,
|
||||
NormalIntensityAttr: normalIntensityAttr,
|
||||
NoItalicAttr: noItalicAttr,
|
||||
NoUnderlineAttr: noUnderlineAttr,
|
||||
NoBlinkAttr: noBlinkAttr,
|
||||
NoReverseAttr: noReverseAttr,
|
||||
NoConcealAttr: noConcealAttr,
|
||||
NoStrikethroughAttr: noStrikethroughAttr,
|
||||
BlackForegroundColorAttr: blackForegroundColorAttr,
|
||||
RedForegroundColorAttr: redForegroundColorAttr,
|
||||
GreenForegroundColorAttr: greenForegroundColorAttr,
|
||||
YellowForegroundColorAttr: yellowForegroundColorAttr,
|
||||
BlueForegroundColorAttr: blueForegroundColorAttr,
|
||||
MagentaForegroundColorAttr: magentaForegroundColorAttr,
|
||||
CyanForegroundColorAttr: cyanForegroundColorAttr,
|
||||
WhiteForegroundColorAttr: whiteForegroundColorAttr,
|
||||
ExtendedForegroundColorAttr: extendedForegroundColorAttr,
|
||||
DefaultForegroundColorAttr: defaultForegroundColorAttr,
|
||||
BlackBackgroundColorAttr: blackBackgroundColorAttr,
|
||||
RedBackgroundColorAttr: redBackgroundColorAttr,
|
||||
GreenBackgroundColorAttr: greenBackgroundColorAttr,
|
||||
YellowBackgroundColorAttr: yellowBackgroundColorAttr,
|
||||
BlueBackgroundColorAttr: blueBackgroundColorAttr,
|
||||
MagentaBackgroundColorAttr: magentaBackgroundColorAttr,
|
||||
CyanBackgroundColorAttr: cyanBackgroundColorAttr,
|
||||
WhiteBackgroundColorAttr: whiteBackgroundColorAttr,
|
||||
ExtendedBackgroundColorAttr: extendedBackgroundColorAttr,
|
||||
DefaultBackgroundColorAttr: defaultBackgroundColorAttr,
|
||||
ExtendedUnderlineColorAttr: extendedUnderlineColorAttr,
|
||||
DefaultUnderlineColorAttr: defaultUnderlineColorAttr,
|
||||
BrightBlackForegroundColorAttr: brightBlackForegroundColorAttr,
|
||||
BrightRedForegroundColorAttr: brightRedForegroundColorAttr,
|
||||
BrightGreenForegroundColorAttr: brightGreenForegroundColorAttr,
|
||||
BrightYellowForegroundColorAttr: brightYellowForegroundColorAttr,
|
||||
BrightBlueForegroundColorAttr: brightBlueForegroundColorAttr,
|
||||
BrightMagentaForegroundColorAttr: brightMagentaForegroundColorAttr,
|
||||
BrightCyanForegroundColorAttr: brightCyanForegroundColorAttr,
|
||||
BrightWhiteForegroundColorAttr: brightWhiteForegroundColorAttr,
|
||||
BrightBlackBackgroundColorAttr: brightBlackBackgroundColorAttr,
|
||||
BrightRedBackgroundColorAttr: brightRedBackgroundColorAttr,
|
||||
BrightGreenBackgroundColorAttr: brightGreenBackgroundColorAttr,
|
||||
BrightYellowBackgroundColorAttr: brightYellowBackgroundColorAttr,
|
||||
BrightBlueBackgroundColorAttr: brightBlueBackgroundColorAttr,
|
||||
BrightMagentaBackgroundColorAttr: brightMagentaBackgroundColorAttr,
|
||||
BrightCyanBackgroundColorAttr: brightCyanBackgroundColorAttr,
|
||||
BrightWhiteBackgroundColorAttr: brightWhiteBackgroundColorAttr,
|
||||
}
|
||||
|
30
vendor/github.com/charmbracelet/x/ansi/status.go
generated
vendored
30
vendor/github.com/charmbracelet/x/ansi/status.go
generated
vendored
@ -11,10 +11,10 @@ type StatusReport interface {
|
||||
StatusReport() int
|
||||
}
|
||||
|
||||
// ANSIReport represents an ANSI terminal status report.
|
||||
// ANSIStatusReport represents an ANSI terminal status report.
|
||||
type ANSIStatusReport int //nolint:revive
|
||||
|
||||
// Report returns the status report identifier.
|
||||
// StatusReport returns the status report identifier.
|
||||
func (s ANSIStatusReport) StatusReport() int {
|
||||
return int(s)
|
||||
}
|
||||
@ -22,7 +22,7 @@ func (s ANSIStatusReport) StatusReport() int {
|
||||
// DECStatusReport represents a DEC terminal status report.
|
||||
type DECStatusReport int
|
||||
|
||||
// Status returns the status report identifier.
|
||||
// StatusReport returns the status report identifier.
|
||||
func (s DECStatusReport) StatusReport() int {
|
||||
return int(s)
|
||||
}
|
||||
@ -89,6 +89,16 @@ const RequestCursorPositionReport = "\x1b[6n"
|
||||
// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
|
||||
const RequestExtendedCursorPositionReport = "\x1b[?6n"
|
||||
|
||||
// RequestLightDarkReport is a control sequence that requests the terminal to
|
||||
// report its operating system light/dark color preference. Supported terminals
|
||||
// should respond with a [LightDarkReport] sequence as follows:
|
||||
//
|
||||
// CSI ? 997 ; 1 n for dark mode
|
||||
// CSI ? 997 ; 2 n for light mode
|
||||
//
|
||||
// See: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
|
||||
const RequestLightDarkReport = "\x1b[?996n"
|
||||
|
||||
// CursorPositionReport (CPR) is a control sequence that reports the cursor's
|
||||
// position.
|
||||
//
|
||||
@ -142,3 +152,17 @@ func ExtendedCursorPositionReport(line, column, page int) string {
|
||||
func DECXCPR(line, column, page int) string {
|
||||
return ExtendedCursorPositionReport(line, column, page)
|
||||
}
|
||||
|
||||
// LightDarkReport is a control sequence that reports the terminal's operating
|
||||
// system light/dark color preference.
|
||||
//
|
||||
// CSI ? 997 ; 1 n for dark mode
|
||||
// CSI ? 997 ; 2 n for light mode
|
||||
//
|
||||
// See: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
|
||||
func LightDarkReport(dark bool) string {
|
||||
if dark {
|
||||
return "\x1b[?997;1n"
|
||||
}
|
||||
return "\x1b[?997;2n"
|
||||
}
|
||||
|
35
vendor/github.com/charmbracelet/x/ansi/style.go
generated
vendored
35
vendor/github.com/charmbracelet/x/ansi/style.go
generated
vendored
@ -17,6 +17,26 @@ type Attr = int
|
||||
// Style represents an ANSI SGR (Select Graphic Rendition) style.
|
||||
type Style []string
|
||||
|
||||
// NewStyle returns a new style with the given attributes.
|
||||
func NewStyle(attrs ...Attr) Style {
|
||||
if len(attrs) == 0 {
|
||||
return Style{}
|
||||
}
|
||||
s := make(Style, 0, len(attrs))
|
||||
for _, a := range attrs {
|
||||
attr, ok := attrStrings[a]
|
||||
if ok {
|
||||
s = append(s, attr)
|
||||
} else {
|
||||
if a < 0 {
|
||||
a = 0
|
||||
}
|
||||
s = append(s, strconv.Itoa(a))
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// String returns the ANSI SGR (Select Graphic Rendition) style sequence for
|
||||
// the given style.
|
||||
func (s Style) String() string {
|
||||
@ -127,11 +147,6 @@ func (s Style) Strikethrough() Style {
|
||||
return append(s, strikethroughAttr)
|
||||
}
|
||||
|
||||
// NoBold appends the no bold style attribute to the style.
|
||||
func (s Style) NoBold() Style {
|
||||
return append(s, noBoldAttr)
|
||||
}
|
||||
|
||||
// NormalIntensity appends the normal intensity style attribute to the style.
|
||||
func (s Style) NormalIntensity() Style {
|
||||
return append(s, normalIntensityAttr)
|
||||
@ -236,7 +251,6 @@ const (
|
||||
ReverseAttr Attr = 7
|
||||
ConcealAttr Attr = 8
|
||||
StrikethroughAttr Attr = 9
|
||||
NoBoldAttr Attr = 21 // Some terminals treat this as double underline.
|
||||
NormalIntensityAttr Attr = 22
|
||||
NoItalicAttr Attr = 23
|
||||
NoUnderlineAttr Attr = 24
|
||||
@ -298,7 +312,6 @@ const (
|
||||
reverseAttr = "7"
|
||||
concealAttr = "8"
|
||||
strikethroughAttr = "9"
|
||||
noBoldAttr = "21"
|
||||
normalIntensityAttr = "22"
|
||||
noItalicAttr = "23"
|
||||
noUnderlineAttr = "24"
|
||||
@ -581,7 +594,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
||||
B: uint8(b), //nolint:gosec
|
||||
A: 0xff,
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
|
||||
case 3: // CMY direct color
|
||||
if len(params) < 5 {
|
||||
@ -599,7 +612,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
||||
Y: uint8(y), //nolint:gosec
|
||||
K: 0,
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
|
||||
case 4: // CMYK direct color
|
||||
if len(params) < 6 {
|
||||
@ -617,7 +630,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
||||
Y: uint8(y), //nolint:gosec
|
||||
K: uint8(k), //nolint:gosec
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
|
||||
case 5: // indexed color
|
||||
if len(params) < 3 {
|
||||
@ -652,7 +665,7 @@ func ReadStyleColor(params Params, co *color.Color) (n int) {
|
||||
B: uint8(b), //nolint:gosec
|
||||
A: uint8(a), //nolint:gosec
|
||||
}
|
||||
return
|
||||
return //nolint:nakedret
|
||||
|
||||
default:
|
||||
return 0
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user