diff --git a/bot/command/impl/statistics/statsuser.go b/bot/command/impl/statistics/statsuser.go index 2f318954..07da1b28 100644 --- a/bot/command/impl/statistics/statsuser.go +++ b/bot/command/impl/statistics/statsuser.go @@ -65,6 +65,7 @@ func (StatsUserCommand) Execute(ctx registry.CommandContext, userId uint64) { var isBlacklisted bool var totalTickets int var openTickets int + var ticketLimit uint8 group, _ := errgroup.WithContext(ctx) @@ -97,6 +98,19 @@ func (StatsUserCommand) Execute(ctx registry.CommandContext, userId uint64) { return err }) + group.Go(func() (err error) { + span := sentry.StartSpan(span.Context(), "TicketLimit") + defer span.Finish() + + settings, err := dbclient.Client.Settings.Get(ctx, ctx.GuildId()) + if err != nil { + return err + } + + ticketLimit = settings.TicketLimit + return nil + }) + if err := group.Wait(); err != nil { ctx.HandleError(err) return @@ -109,7 +123,7 @@ func (StatsUserCommand) Execute(ctx registry.CommandContext, userId uint64) { fmt.Sprintf("**Permission Level**: Regular"), fmt.Sprintf("**Is Blacklisted**: %s", strconv.FormatBool(isBlacklisted)), fmt.Sprintf("**Total Tickets**: %d", totalTickets), - fmt.Sprintf("**Open Tickets**: %d", openTickets), + fmt.Sprintf("**Open Tickets**: %s", formatOpenTickets(openTickets, ticketLimit)), } var topSection []component.Component @@ -390,3 +404,11 @@ func (StatsUserCommand) Execute(ctx registry.CommandContext, userId uint64) { span.Finish() } } + +func formatOpenTickets(openTickets int, ticketLimit uint8) string { + if ticketLimit == 0 { + return strconv.Itoa(openTickets) + } + + return fmt.Sprintf("%d / %d", openTickets, ticketLimit) +} diff --git a/bot/logic/open.go b/bot/logic/open.go index dd9a2c38..df5780eb 100644 --- a/bot/logic/open.go +++ b/bot/logic/open.go @@ -80,14 +80,7 @@ func OpenTicket(ctx context.Context, cmd registry.InteractionContext, panel *dat // Check ticket limit before ratelimit token to prevent 1 person from stopping everyone opening tickets violatesTicketLimit, limit := getTicketLimit(ctx, cmd, panel) if violatesTicketLimit { - // Notify the user - ticketsPluralised := "ticket" - if limit > 1 { - ticketsPluralised += "s" - } - - // TODO: Use translation of tickets - cmd.Reply(customisation.Red, i18n.Error, i18n.MessageTicketLimitReached, limit, ticketsPluralised) + replyTicketLimitReached(cmd, limit) return database.Ticket{}, fmt.Errorf("ticket limit reached") } @@ -774,7 +767,29 @@ func refreshCachedChannels(ctx context.Context, worker *worker.Context, guildId return worker.Cache.ReplaceChannels(ctx, guildId, channels) } -// has hit ticket limit, ticket limit +// TODO: Use translation of tickets +func replyTicketLimitReached(cmd registry.CommandContext, limit int) { + ticketsPluralised := "ticket" + if limit > 1 { + ticketsPluralised += "s" + } + + cmd.Reply(customisation.Red, i18n.Error, i18n.MessageTicketLimitReached, limit, ticketsPluralised) +} + +// Both limits apply independently; a limit of 0 disables that check. +func ticketLimitVerdict(panelLimit, guildLimit uint8, panelOpenCount, guildOpenCount int) (bool, int) { + if panelLimit > 0 && panelOpenCount >= int(panelLimit) { + return true, int(panelLimit) + } + + if guildLimit > 0 && guildOpenCount >= int(guildLimit) { + return true, int(guildLimit) + } + + return false, int(guildLimit) +} + func getTicketLimit(ctx context.Context, cmd registry.CommandContext, panel *database.Panel) (bool, int) { isStaff, err := cmd.UserPermissionLevel(ctx) if err != nil { @@ -786,24 +801,37 @@ func getTicketLimit(ctx context.Context, cmd registry.CommandContext, panel *dat return false, 50 } - var openTicketCount int - var ticketLimit uint8 + var panelLimit uint8 + if panel != nil && panel.TicketLimit != nil { + panelLimit = *panel.TicketLimit + } + + var guildLimit uint8 + var guildOpenCount, panelOpenCount int group, _ := errgroup.WithContext(ctx) - if panel != nil && panel.TicketLimit != nil && *panel.TicketLimit > 0 { - ticketLimit = *panel.TicketLimit + group.Go(func() error { + settings, err := dbclient.Client.Settings.Get(ctx, cmd.GuildId()) + if err != nil { + return err + } + + guildLimit = settings.TicketLimit + return nil + }) + + group.Go(func() (err error) { + guildOpenCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId()) + return + }) + + if panelLimit > 0 { group.Go(func() (err error) { - openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel( + panelOpenCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel( ctx, cmd.GuildId(), cmd.UserId(), panel.PanelId) return }) - } else { - ticketLimit = 5 - group.Go(func() (err error) { - openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId()) - return - }) } if err := group.Wait(); err != nil { @@ -811,7 +839,7 @@ func getTicketLimit(ctx context.Context, cmd registry.CommandContext, panel *dat return true, 1 } - return openTicketCount >= int(ticketLimit), int(ticketLimit) + return ticketLimitVerdict(panelLimit, guildLimit, panelOpenCount, guildOpenCount) } func createWebhook(ctx context.Context, c registry.CommandContext, ticketId int, guildId, channelId uint64) error { diff --git a/bot/logic/reopen.go b/bot/logic/reopen.go index d5609154..32482bb6 100644 --- a/bot/logic/reopen.go +++ b/bot/logic/reopen.go @@ -49,33 +49,39 @@ func ReopenTicket(ctx context.Context, cmd registry.CommandContext, ticketId int } } - var ticketLimit uint8 - var openTicketCount int + var panelLimit uint8 + if panel != nil && panel.TicketLimit != nil { + panelLimit = *panel.TicketLimit + } + + settings, err := dbclient.Client.Settings.Get(ctx, cmd.GuildId()) + if err != nil { + cmd.HandleError(err) + return + } + + guildLimit := settings.TicketLimit - if panel != nil && panel.TicketLimit != nil && *panel.TicketLimit > 0 { - ticketLimit = *panel.TicketLimit - openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel(ctx, cmd.GuildId(), cmd.UserId(), panel.PanelId) + var panelOpenCount, guildOpenCount int + + if panelLimit > 0 { + panelOpenCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel(ctx, cmd.GuildId(), cmd.UserId(), panel.PanelId) if err != nil { cmd.HandleError(err) return } - } else { - ticketLimit = 5 - openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId()) + } + + if guildLimit > 0 { + guildOpenCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId()) if err != nil { cmd.HandleError(err) return } } - if openTicketCount >= int(ticketLimit) { - // TODO: Use translation of tickets - ticketsPluralised := "ticket" - if ticketLimit > 1 { - ticketsPluralised += "s" - } - - cmd.Reply(customisation.Red, i18n.Error, i18n.MessageTicketLimitReached, ticketLimit, ticketsPluralised) + if violates, limit := ticketLimitVerdict(panelLimit, guildLimit, panelOpenCount, guildOpenCount); violates { + replyTicketLimitReached(cmd, limit) return } } diff --git a/bot/logic/welcomemessage.go b/bot/logic/welcomemessage.go index 32a2ed4e..0324449f 100644 --- a/bot/logic/welcomemessage.go +++ b/bot/logic/welcomemessage.go @@ -531,13 +531,29 @@ var substitutions = map[string]PlaceholderSubstitutionFunc{ return strconv.Itoa(tickets) }, "ticket_limit": func(ctx context.Context, _ *worker.Context, ticket database.Ticket) string { + var panelLimit uint8 if ticket.PanelId != nil { panel, err := dbclient.Client.Panel.GetById(ctx, *ticket.PanelId) - if err == nil && panel.TicketLimit != nil && *panel.TicketLimit > 0 { - return strconv.Itoa(int(*panel.TicketLimit)) + if err == nil && panel.TicketLimit != nil { + panelLimit = *panel.TicketLimit } } - return "5" + + guildLimit := database.DefaultTicketLimit + if settings, err := dbclient.Client.Settings.Get(ctx, ticket.GuildId); err == nil { + guildLimit = settings.TicketLimit + } + + effective := guildLimit + if panelLimit > 0 && (effective == 0 || panelLimit < effective) { + effective = panelLimit + } + + if effective == 0 { + return "unlimited" + } + + return strconv.Itoa(int(effective)) }, "rating_count": func(ctx context.Context, _ *worker.Context, ticket database.Ticket) string { ctx, cancel := context.WithTimeout(context.Background(), substitutionTimeout) diff --git a/go.mod b/go.mod index 3bcf40db..1f0919d1 100644 --- a/go.mod +++ b/go.mod @@ -1,22 +1,22 @@ module github.com/TicketsBot-cloud/worker -go 1.25.0 +go 1.26.0 // replace github.com/TicketsBot-cloud/database => ../database // replace github.com/TicketsBot-cloud/common => ../common -//replace github.com/TicketsBot-cloud/gdl => ../gdl +// replace github.com/TicketsBot-cloud/gdl => ../gdl -//replace github.com/TicketsBot-cloud/archiverclient => ../archiverclient +// replace github.com/TicketsBot-cloud/archiverclient => ../archiverclient -//replace github.com/TicketsBot-cloud/logarchiver => ../logarchiver +// replace github.com/TicketsBot-cloud/logarchiver => ../logarchiver require ( cloud.google.com/go/profiler v0.4.2 github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704 - github.com/TicketsBot-cloud/common v0.0.0-20260827064609-69131fc7bd3e - github.com/TicketsBot-cloud/database v0.0.0-20260827064551-53077b598c5f + github.com/TicketsBot-cloud/common v0.0.0-20260905165836-38e4090764a4 + github.com/TicketsBot-cloud/database v0.0.0-20260909063631-6804baaaa52b github.com/TicketsBot-cloud/gdl v0.0.0-20260426095953-999472e6e538 github.com/caarlos0/env/v10 v10.0.0 github.com/elliotchance/orderedmap v1.8.0 @@ -37,9 +37,9 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/zap v1.28.0 golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 - golang.org/x/net v0.57.0 - golang.org/x/sync v0.22.0 - golang.org/x/tools v0.48.0 + golang.org/x/net v0.58.0 + golang.org/x/sync v0.23.0 + golang.org/x/tools v0.49.0 gopkg.in/alexcesaro/statsd.v2 v2.0.0 ) @@ -128,12 +128,12 @@ require ( go.opentelemetry.io/otel/trace v1.36.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.17.0 // indirect - golang.org/x/crypto v0.55.0 // indirect - golang.org/x/mod v0.38.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/mod v0.41.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.47.0 // indirect - golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.41.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/term v0.46.0 // indirect + golang.org/x/text v0.42.0 // indirect golang.org/x/time v0.11.0 // indirect google.golang.org/api v0.232.0 // indirect google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect diff --git a/go.sum b/go.sum index 7acfe894..6c35c2eb 100644 --- a/go.sum +++ b/go.sum @@ -27,10 +27,10 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0 github.com/ReneKroon/ttlcache v1.6.0/go.mod h1:DG6nbhXKUQhrExfwwLuZUdH7UnRDDRA1IW+nBuCssvs= github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704 h1:liLfvCrzoJ89DXFHzsd1iK3cyP8s4i0CnZPRFEj53zg= github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704/go.mod h1:Mux1bEPpOHwRw1wo6Fa6qJLJH9Erk9qv1yAIfLi1Wmw= -github.com/TicketsBot-cloud/common v0.0.0-20260827064609-69131fc7bd3e h1:66mDH3lvotbWSgQXNVbssCvUgy6Yg1mqKl7RmEdr6y4= -github.com/TicketsBot-cloud/common v0.0.0-20260827064609-69131fc7bd3e/go.mod h1:yL+VPSYNVK5gxUkA+fbb0WdTjGfWXnr7ScfL0rwk29g= -github.com/TicketsBot-cloud/database v0.0.0-20260827064551-53077b598c5f h1:5dcXYEUJKRvB+csN5mbTycftijY9NAIhmV4EtuYoNok= -github.com/TicketsBot-cloud/database v0.0.0-20260827064551-53077b598c5f/go.mod h1:HQXAgmNSm7/FmBYwcsa6qpZqMrDhbLoEl+AyqFQ+RwY= +github.com/TicketsBot-cloud/common v0.0.0-20260905165836-38e4090764a4 h1:zcPcJ+03xW9qalqzqllM6j0ZPdhuL+mrtGw8woLrAMo= +github.com/TicketsBot-cloud/common v0.0.0-20260905165836-38e4090764a4/go.mod h1:yL+VPSYNVK5gxUkA+fbb0WdTjGfWXnr7ScfL0rwk29g= +github.com/TicketsBot-cloud/database v0.0.0-20260909063631-6804baaaa52b h1:I7gkfG8EKX9DnfpWrSUlNHBsD1H3EDWpvpL6Yr4OanY= +github.com/TicketsBot-cloud/database v0.0.0-20260909063631-6804baaaa52b/go.mod h1:0fKn7nPX6KeljYNQtGQiuZ5aJ/TczgXvBhnbz+4GEc8= github.com/TicketsBot-cloud/gdl v0.0.0-20260426095953-999472e6e538 h1:ewKw1Wv1x/yi8h1IH7EofcYnPUxWZaVTIPFkT97nhn0= github.com/TicketsBot-cloud/gdl v0.0.0-20260426095953-999472e6e538/go.mod h1:CdwBR2egPtxUXjD2CgC9ZwfuB8dz9HPePM8nuG6dt7Y= github.com/TicketsBot-cloud/logarchiver v0.0.0-20251018211319-7a7df5cacbdc h1:qTLNpCvIqM7UwZ6MdWQ9EztcDsIJfHh+VJdG+ULLEaA= @@ -414,8 +414,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -423,8 +423,8 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= -golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= +golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -434,15 +434,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -462,16 +462,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= +golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -481,8 +481,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -496,8 +496,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= -golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=