From 01fff665c60e2b25e65205f706845517881db149 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 10:11:19 +0000 Subject: [PATCH 001/313] fix(frontend): focus quick actions input after modal opens The Modal mounts the via v-if and calls showModal() in a follow-up flush, so v-focus runs while the dialog is still closed and its focus() call is dropped. The existing rAF retry was gated on quick-add mode, leaving Ctrl+K in the regular app with no focused input. Run the retry whenever the quick actions become active and keep the command pre-selection scoped to quick-add mode. --- .../src/components/quick-actions/QuickActions.vue | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/quick-actions/QuickActions.vue b/frontend/src/components/quick-actions/QuickActions.vue index fe39b45de..13605fe4f 100644 --- a/frontend/src/components/quick-actions/QuickActions.vue +++ b/frontend/src/components/quick-actions/QuickActions.vue @@ -190,12 +190,17 @@ watchEffect(() => { let focusRafId: number | null = null watchEffect(() => { - if (active.value && isQuickAddMode) { - selectedCmd.value = commands.value.newTask + if (active.value) { + if (isQuickAddMode) { + selectedCmd.value = commands.value.newTask + } // The input may not be focusable yet due to: - // 1. Modal transition (v-if + ) delaying DOM readiness - // 2. Electron window not yet visible (shown after did-finish-load) + // 1. Modal mounts the via v-if and then calls showModal() in a + // follow-up flush, so v-focus fires while the dialog is still closed + // and the focus() call is dropped. + // 2. In quick-add mode the Electron window isn't visible until + // did-finish-load. // Retry with rAF until focus actually lands on the input. const tryFocus = () => { if (!active.value) { From 3d75ca049b16e426a01329322aac9496a59a7017 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 1 May 2026 11:13:12 +0200 Subject: [PATCH 002/313] fix(auth): don't panic on /token/test with API token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JWT skipper bypassed validation entirely for /token/test when the bearer was an API token, leaving "user" unset in the context. CheckToken then type-asserted it to *jwt.Token and panicked. Validate the API token in the skipper but skip the route permission check (since /token/test is not exposed in the API token route registry, no token can hold explicit permission for it). Drop the now-redundant JWT assertion in CheckToken — auth has already passed by the time the handler runs. --- pkg/routes/api/v1/token_check.go | 11 ++--------- pkg/routes/api_tokens.go | 11 ++++------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/pkg/routes/api/v1/token_check.go b/pkg/routes/api/v1/token_check.go index cd4d3492d..42286b19e 100644 --- a/pkg/routes/api/v1/token_check.go +++ b/pkg/routes/api/v1/token_check.go @@ -19,20 +19,13 @@ package v1 import ( "net/http" - "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" - "github.com/golang-jwt/jwt/v5" "github.com/labstack/echo/v5" ) -// CheckToken checks prints a message if the token is valid or not. Currently only used for testing purposes. +// CheckToken returns 418 if the bearer token is valid. Used for testing. func CheckToken(c *echo.Context) error { - - user := c.Get("user").(*jwt.Token) - - log.Debugf("token valid: %t", user.Valid) - - return c.JSON(418, models.Message{Message: "🍵"}) + return c.JSON(http.StatusTeapot, models.Message{Message: "🍵"}) } // TestToken returns a simple test message. Used for testing purposes. diff --git a/pkg/routes/api_tokens.go b/pkg/routes/api_tokens.go index 40f48fec7..0e29911c9 100644 --- a/pkg/routes/api_tokens.go +++ b/pkg/routes/api_tokens.go @@ -46,11 +46,8 @@ func SetupTokenMiddleware() echo.MiddlewareFunc { for _, s := range authHeader { if strings.HasPrefix(s, "Bearer "+models.APITokenPrefix) { - if c.Request().URL.Path == "/api/v1/token/test" { - return true - } - - err := checkAPITokenAndPutItInContext(s, c) + skipRouteCheck := c.Request().URL.Path == "/api/v1/token/test" + err := checkAPITokenAndPutItInContext(s, c, skipRouteCheck) return err == nil } } @@ -71,14 +68,14 @@ func SetupTokenMiddleware() echo.MiddlewareFunc { }) } -func checkAPITokenAndPutItInContext(tokenHeaderValue string, c *echo.Context) error { +func checkAPITokenAndPutItInContext(tokenHeaderValue string, c *echo.Context, skipRouteCheck bool) error { token, u, err := auth.ValidateAPITokenString(strings.TrimPrefix(tokenHeaderValue, "Bearer ")) if err != nil { log.Debugf("[auth] API token validation failed: %v", err) return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized") } - if !models.CanDoAPIRoute(c, token) { + if !skipRouteCheck && !models.CanDoAPIRoute(c, token) { log.Debugf("[auth] Tried authenticating with token %d but it does not have permission to do this route", token.ID) return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized") } From 4c3f0231e9d1de51b642ca1e21e9b44b02c47a7b Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:45:51 +0200 Subject: [PATCH 003/313] feat(config): add service.enablebotusers flag --- config-raw.json | 5 +++++ pkg/config/config.go | 2 ++ 2 files changed, 7 insertions(+) diff --git a/config-raw.json b/config-raw.json index dd395b768..c49239e6b 100644 --- a/config-raw.json +++ b/config-raw.json @@ -113,6 +113,11 @@ "default_value": "true", "comment": "If true, will allow users to request the complete deletion of their account. When using external authentication methods\nit may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands\nfor user deletion." }, + { + "key": "enablebotusers", + "default_value": "true", + "comment": "If enabled (default), users can create bot users that interact with Vikunja via the API only. Set to false to disable the feature entirely." + }, { "key": "maxavatarsize", "default_value": "1024", diff --git a/pkg/config/config.go b/pkg/config/config.go index 1941f7f0b..099c72e9c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -64,6 +64,7 @@ const ( ServiceTestingtoken Key = `service.testingtoken` ServiceEnableEmailReminders Key = `service.enableemailreminders` ServiceEnableUserDeletion Key = `service.enableuserdeletion` + ServiceEnableBotUsers Key = `service.enablebotusers` ServiceMaxAvatarSize Key = `service.maxavatarsize` ServiceAllowIconChanges Key = `service.allowiconchanges` ServiceCustomLogoURL Key = `service.customlogourl` @@ -360,6 +361,7 @@ func InitDefaultConfig() { ServiceEnableTotp.setDefault(true) ServiceEnableEmailReminders.setDefault(true) ServiceEnableUserDeletion.setDefault(true) + ServiceEnableBotUsers.setDefault(true) ServiceMaxAvatarSize.setDefault(1024) ServiceDemoMode.setDefault(false) ServiceAllowIconChanges.setDefault(true) From 83c5190c9b5b1fe84692d409c33fb717efdcf9c4 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:48:06 +0200 Subject: [PATCH 004/313] feat(user): add BotOwnerID field and IsBot helper --- pkg/user/user.go | 17 ++++++++++++++--- pkg/user/user_test.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/pkg/user/user.go b/pkg/user/user.go index 2d46341f8..ae2305628 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -110,9 +110,12 @@ type User struct { OverdueTasksRemindersEnabled bool `xorm:"bool default true index" json:"-"` OverdueTasksRemindersTime string `xorm:"varchar(5) not null default '09:00'" json:"-"` DefaultProjectID int64 `xorm:"bigint null index" json:"-"` - WeekStart int `xorm:"null" json:"-"` - Language string `xorm:"varchar(50) null" json:"-" valid:"language"` - Timezone string `xorm:"varchar(255) null" json:"-"` + // BotOwnerID is the ID of the owning (human) user if this user is a bot. + // A non-zero value means this user is a bot and cannot authenticate via password. + BotOwnerID int64 `xorm:"bigint null index" json:"bot_owner_id,omitempty"` + WeekStart int `xorm:"null" json:"-"` + Language string `xorm:"varchar(50) null" json:"-" valid:"language"` + Timezone string `xorm:"varchar(255) null" json:"-"` DeletionScheduledAt time.Time `xorm:"datetime null" json:"-"` DeletionLastReminderSent time.Time `xorm:"datetime null" json:"-"` @@ -152,6 +155,9 @@ func (u *User) RouteForDB() int64 { } func (u *User) ShouldNotify(sessions ...*xorm.Session) (bool, error) { + if u.IsBot() { + return false, nil + } var s *xorm.Session if len(sessions) > 0 && sessions[0] != nil { s = sessions[0] @@ -178,6 +184,11 @@ func (u *User) GetID() int64 { return u.ID } +// IsBot reports whether this user is a bot (owned by another user). +func (u *User) IsBot() bool { + return u.BotOwnerID > 0 +} + // TableName returns the table name for users func (*User) TableName() string { return "users" diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index a5bc263c7..25f9802c3 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -25,6 +25,17 @@ import ( "github.com/stretchr/testify/require" ) +func TestUser_IsBot(t *testing.T) { + t.Run("regular user", func(t *testing.T) { + u := &User{ID: 1} + assert.False(t, u.IsBot()) + }) + t.Run("bot user", func(t *testing.T) { + u := &User{ID: 2, BotOwnerID: 1} + assert.True(t, u.IsBot()) + }) +} + func TestCreateUser(t *testing.T) { // Our dummy user for testing dummyuser := &User{ From c2398340707a20cb1ccfa13d3b9abf868b541882 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:48:45 +0200 Subject: [PATCH 005/313] feat(migration): add bot_owner_id column to users --- pkg/migration/20260405194817.go | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 pkg/migration/20260405194817.go diff --git a/pkg/migration/20260405194817.go b/pkg/migration/20260405194817.go new file mode 100644 index 000000000..5c9927040 --- /dev/null +++ b/pkg/migration/20260405194817.go @@ -0,0 +1,43 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migration + +import ( + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +type users20260405194817 struct { + BotOwnerID int64 `xorm:"bigint null index"` +} + +func (users20260405194817) TableName() string { + return "users" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20260405194817", + Description: "Add bot_owner_id column to users", + Migrate: func(tx *xorm.Engine) error { + return tx.Sync(users20260405194817{}) + }, + Rollback: func(tx *xorm.Engine) error { + return nil + }, + }) +} From a262c6a848013f2e0c245ac414b510a3664073a4 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:50:58 +0200 Subject: [PATCH 006/313] feat(user): add bot-related error types --- pkg/user/error.go | 106 +++++++++++++++++++++++++++++++++++++++++ pkg/user/error_test.go | 52 ++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 pkg/user/error_test.go diff --git a/pkg/user/error.go b/pkg/user/error.go index 1013a9e2d..e9007c918 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -792,3 +792,109 @@ func (err ErrLastAdmin) HTTPError() web.HTTPError { Message: "Cannot remove the last remaining instance admin.", } } + +// ErrAccountIsBot represents an error where a bot user tried to authenticate interactively. +type ErrAccountIsBot struct { + UserID int64 +} + +// IsErrAccountIsBot checks if an error is a ErrAccountIsBot. +func IsErrAccountIsBot(err error) bool { + _, ok := err.(*ErrAccountIsBot) + return ok +} + +func (err *ErrAccountIsBot) Error() string { + return fmt.Sprintf("Account is a bot [UserID: %d]", err.UserID) +} + +// ErrCodeAccountIsBot holds the unique world-error code of this error +const ErrCodeAccountIsBot = 1031 + +// HTTPError holds the http error description +func (err *ErrAccountIsBot) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusPreconditionFailed, + Code: ErrCodeAccountIsBot, + Message: "This account is a bot and cannot log in interactively.", + } +} + +// ErrBotUsersDisabled represents an error where the bot users feature is disabled. +type ErrBotUsersDisabled struct{} + +// IsErrBotUsersDisabled checks if an error is a ErrBotUsersDisabled. +func IsErrBotUsersDisabled(err error) bool { + _, ok := err.(*ErrBotUsersDisabled) + return ok +} + +func (err *ErrBotUsersDisabled) Error() string { + return "Bot users feature is disabled" +} + +// ErrCodeBotUsersDisabled holds the unique world-error code of this error +const ErrCodeBotUsersDisabled = 1032 + +// HTTPError holds the http error description +func (err *ErrBotUsersDisabled) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusForbidden, + Code: ErrCodeBotUsersDisabled, + Message: "Bot users are disabled on this instance.", + } +} + +// ErrBotNotOwned represents an error where a user tried to operate on a bot they do not own. +type ErrBotNotOwned struct { + UserID int64 +} + +// IsErrBotNotOwned checks if an error is a ErrBotNotOwned. +func IsErrBotNotOwned(err error) bool { + _, ok := err.(*ErrBotNotOwned) + return ok +} + +func (err *ErrBotNotOwned) Error() string { + return fmt.Sprintf("Bot not owned by caller [UserID: %d]", err.UserID) +} + +// ErrCodeBotNotOwned holds the unique world-error code of this error +const ErrCodeBotNotOwned = 1033 + +// HTTPError holds the http error description +func (err *ErrBotNotOwned) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusForbidden, + Code: ErrCodeBotNotOwned, + Message: "You do not own this bot user.", + } +} + +// ErrBotUsernameMustHavePrefix represents an error where a bot username is missing the bot- prefix. +type ErrBotUsernameMustHavePrefix struct { + Username string +} + +// IsErrBotUsernameMustHavePrefix checks if an error is a ErrBotUsernameMustHavePrefix. +func IsErrBotUsernameMustHavePrefix(err error) bool { + _, ok := err.(*ErrBotUsernameMustHavePrefix) + return ok +} + +func (err *ErrBotUsernameMustHavePrefix) Error() string { + return fmt.Sprintf("Bot username must start with 'bot-' [Username: %s]", err.Username) +} + +// ErrCodeBotUsernameMustHavePrefix holds the unique world-error code of this error +const ErrCodeBotUsernameMustHavePrefix = 1034 + +// HTTPError holds the http error description +func (err *ErrBotUsernameMustHavePrefix) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusBadRequest, + Code: ErrCodeBotUsernameMustHavePrefix, + Message: "Bot usernames must start with the 'bot-' prefix.", + } +} diff --git a/pkg/user/error_test.go b/pkg/user/error_test.go new file mode 100644 index 000000000..de458f74f --- /dev/null +++ b/pkg/user/error_test.go @@ -0,0 +1,52 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package user + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestErrAccountIsBot(t *testing.T) { + err := &ErrAccountIsBot{UserID: 42} + assert.True(t, IsErrAccountIsBot(err)) + assert.Equal(t, http.StatusPreconditionFailed, err.HTTPError().HTTPCode) + assert.Equal(t, 1031, err.HTTPError().Code) +} + +func TestErrBotUsersDisabled(t *testing.T) { + err := &ErrBotUsersDisabled{} + assert.True(t, IsErrBotUsersDisabled(err)) + assert.Equal(t, http.StatusForbidden, err.HTTPError().HTTPCode) + assert.Equal(t, 1032, err.HTTPError().Code) +} + +func TestErrBotNotOwned(t *testing.T) { + err := &ErrBotNotOwned{UserID: 7} + assert.True(t, IsErrBotNotOwned(err)) + assert.Equal(t, http.StatusForbidden, err.HTTPError().HTTPCode) + assert.Equal(t, 1033, err.HTTPError().Code) +} + +func TestErrBotUsernameMustHavePrefix(t *testing.T) { + err := &ErrBotUsernameMustHavePrefix{Username: "not-a-bot"} + assert.True(t, IsErrBotUsernameMustHavePrefix(err)) + assert.Equal(t, http.StatusBadRequest, err.HTTPError().HTTPCode) + assert.Equal(t, 1034, err.HTTPError().Code) +} From 506bfa2549fc8a5a5da430371c75de1c079a2bbc Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:52:45 +0200 Subject: [PATCH 007/313] feat(user): reserve bot- username prefix for regular signup --- pkg/user/user_create.go | 7 +++++++ pkg/user/user_test.go | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/pkg/user/user_create.go b/pkg/user/user_create.go index 63ce7e9a2..25e5d4e82 100644 --- a/pkg/user/user_create.go +++ b/pkg/user/user_create.go @@ -149,6 +149,13 @@ func checkIfUserIsValid(user *User) error { } } + // Reserve the bot- prefix for bot users (created via CreateBotUser) + if strings.HasPrefix(user.Username, "bot-") { + return ErrUsernameReserved{ + Username: user.Username, + } + } + return nil } diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index 25f9802c3..b8e5eb22f 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -25,6 +25,20 @@ import ( "github.com/stretchr/testify/require" ) +func TestCreateUser_RejectsBotPrefix(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + _, err := CreateUser(s, &User{ + Username: "bot-evil", + Password: "12345678", + Email: "x@example.com", + }) + require.Error(t, err) + assert.True(t, IsErrUsernameReserved(err)) +} + func TestUser_IsBot(t *testing.T) { t.Run("regular user", func(t *testing.T) { u := &User{ID: 1} From 1637ecd0c727cec10f78d29a7b494bd96c6a14ac Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:54:43 +0200 Subject: [PATCH 008/313] feat(user): add CreateBotUser --- pkg/user/user_create.go | 83 +++++++++++++++++++++++++++++++++++------ pkg/user/user_test.go | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 12 deletions(-) diff --git a/pkg/user/user_create.go b/pkg/user/user_create.go index 25e5d4e82..917ab4454 100644 --- a/pkg/user/user_create.go +++ b/pkg/user/user_create.go @@ -121,12 +121,81 @@ func CreateUser(s *xorm.Session, user *User) (newUser *User, err error) { return newUserOut, err } +// CreateBotUser creates a bot user owned by the given owner. +// Bots have no email or password and cannot authenticate interactively. +// It intentionally bypasses checkIfUserIsValid / checkIfUserExists because +// those enforce email+password and would flag duplicate empty emails. +func CreateBotUser(s *xorm.Session, bot *User, owner *User) (*User, error) { + if owner == nil || owner.ID == 0 { + return nil, ErrNoUsernamePassword{} + } + if owner.IsBot() { + return nil, &ErrBotNotOwned{UserID: owner.ID} + } + + // Reuse the same username format rules as regular user creation + if err := checkUsernameFormat(bot.Username); err != nil { + return nil, err + } + if !strings.HasPrefix(bot.Username, "bot-") { + return nil, &ErrBotUsernameMustHavePrefix{Username: bot.Username} + } + + if _, err := GetUserByUsername(s, bot.Username); err == nil { + return nil, ErrUsernameExists{Username: bot.Username} + } else if !IsErrUserDoesNotExist(err) { + return nil, err + } + + bot.ID = 0 + bot.BotOwnerID = owner.ID + bot.Status = StatusActive + bot.Issuer = IssuerLocal + bot.Password = "" + bot.Email = "" + + if _, err := s.Insert(bot); err != nil { + return nil, err + } + + newBot, err := GetUserByID(s, bot.ID) + if err != nil { + return nil, err + } + + events.DispatchOnCommit(s, &CreatedEvent{User: newBot}) + return newBot, nil +} + // HashPassword hashes a password func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), config.ServiceBcryptRounds.GetInt()) return string(bytes), err } +// checkUsernameFormat validates username format rules shared by regular and bot users. +func checkUsernameFormat(username string) error { + if username == "" { + return ErrNoUsernamePassword{} + } + + if strings.Contains(username, " ") { + return &ErrUsernameMustNotContainSpaces{ + Username: username, + } + } + + // Check if username matches the reserved link-share pattern + linkSharePattern := regexp.MustCompile(`^link-share-\d+$`) + if linkSharePattern.MatchString(username) { + return ErrUsernameReserved{ + Username: username, + } + } + + return nil +} + func checkIfUserIsValid(user *User) error { if user.Email == "" || (user.Issuer != IssuerLocal && user.Subject == "") || @@ -135,18 +204,8 @@ func checkIfUserIsValid(user *User) error { return ErrNoUsernamePassword{} } - if strings.Contains(user.Username, " ") { - return &ErrUsernameMustNotContainSpaces{ - Username: user.Username, - } - } - - // Check if username matches the reserved link-share pattern - linkSharePattern := regexp.MustCompile(`^link-share-\d+$`) - if linkSharePattern.MatchString(user.Username) { - return ErrUsernameReserved{ - Username: user.Username, - } + if err := checkUsernameFormat(user.Username); err != nil { + return err } // Reserve the bot- prefix for bot users (created via CreateBotUser) diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index b8e5eb22f..776a60b5d 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -25,6 +25,75 @@ import ( "github.com/stretchr/testify/require" ) +func TestCreateBotUser(t *testing.T) { + t.Run("success", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := GetUserByID(s, 1) + require.NoError(t, err) + + bot, err := CreateBotUser(s, &User{Username: "bot-reviewer"}, owner) + require.NoError(t, err) + assert.True(t, bot.IsBot()) + assert.Equal(t, owner.ID, bot.BotOwnerID) + assert.Equal(t, StatusActive, bot.Status) + assert.Empty(t, bot.Email) + assert.Empty(t, bot.Password) + }) + t.Run("empty username", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + owner, err := GetUserByID(s, 1) + require.NoError(t, err) + _, err = CreateBotUser(s, &User{Username: ""}, owner) + require.Error(t, err) + }) + t.Run("username with spaces", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + owner, err := GetUserByID(s, 1) + require.NoError(t, err) + _, err = CreateBotUser(s, &User{Username: "bot- name"}, owner) + require.Error(t, err) + assert.True(t, IsErrUsernameMustNotContainSpaces(err)) + }) + t.Run("missing bot- prefix", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + owner, err := GetUserByID(s, 1) + require.NoError(t, err) + _, err = CreateBotUser(s, &User{Username: "reviewer"}, owner) + require.Error(t, err) + assert.True(t, IsErrBotUsernameMustHavePrefix(err)) + }) + t.Run("duplicate username", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + owner, err := GetUserByID(s, 1) + require.NoError(t, err) + _, err = CreateBotUser(s, &User{Username: "bot-dup"}, owner) + require.NoError(t, err) + _, err = CreateBotUser(s, &User{Username: "bot-dup"}, owner) + require.Error(t, err) + assert.True(t, IsErrUsernameExists(err)) + }) + t.Run("bot cannot create bot", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + botOwner := &User{ID: 999, BotOwnerID: 1} + _, err := CreateBotUser(s, &User{Username: "bot-child"}, botOwner) + require.Error(t, err) + assert.True(t, IsErrBotNotOwned(err)) + }) +} + func TestCreateUser_RejectsBotPrefix(t *testing.T) { db.LoadAndAssertFixtures(t) s := db.NewSession() From 8d3ac47605cb7c3c50d0e335c71e2c0e7e542cb0 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:55:17 +0200 Subject: [PATCH 009/313] feat(auth): reject password login for bot users --- pkg/routes/api/v1/login.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/routes/api/v1/login.go b/pkg/routes/api/v1/login.go index e13074bb2..eb92945d1 100644 --- a/pkg/routes/api/v1/login.go +++ b/pkg/routes/api/v1/login.go @@ -62,6 +62,15 @@ func Login(c *echo.Context) (err error) { } if user == nil { + // Check if the user is a bot before attempting password verification, + // because bots have no password hash and bcrypt would fail with a + // misleading error. + existingUser, lookupErr := user2.GetUserByUsername(s, u.Username) + if lookupErr == nil && existingUser.IsBot() { + _ = s.Rollback() + return &user2.ErrAccountIsBot{UserID: existingUser.ID} + } + // This allows us to still have local users while ldap is enabled user, err = user2.CheckUserCredentials(s, &u) if err != nil { From 2e6bcec72ae8f8c3f8989260921dd177ea675701 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:55:50 +0200 Subject: [PATCH 010/313] feat(caldav): reject basic auth for bot users --- pkg/routes/caldav/auth.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/routes/caldav/auth.go b/pkg/routes/caldav/auth.go index a2b617809..930b8f013 100644 --- a/pkg/routes/caldav/auth.go +++ b/pkg/routes/caldav/auth.go @@ -65,6 +65,10 @@ func BasicAuth(c *echo.Context, username, password string) (bool, error) { return false, nil } if u != nil { + if u.IsBot() { + log.Warningf("CalDAV auth rejected for bot user %d", u.ID) + return false, nil + } c.Set("userBasicAuth", u) return true, nil } @@ -103,6 +107,10 @@ func BasicAuth(c *echo.Context, username, password string) (bool, error) { } } if u != nil && err == nil { + if u.IsBot() { + log.Warningf("CalDAV basic auth rejected for bot user %d", u.ID) + return false, nil + } c.Set("userBasicAuth", u) return true, nil } From 74af7af2e36ad33a0a12549c0c6a7f8345bc688a Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:56:16 +0200 Subject: [PATCH 011/313] refactor(api_tokens): preserve pre-set OwnerID in Create --- pkg/models/api_tokens.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/models/api_tokens.go b/pkg/models/api_tokens.go index b432b235c..80a5a10a4 100644 --- a/pkg/models/api_tokens.go +++ b/pkg/models/api_tokens.go @@ -101,7 +101,9 @@ func (t *APIToken) Create(s *xorm.Session, a web.Auth) (err error) { t.TokenHash = HashToken(t.Token, t.TokenSalt) t.TokenLastEight = t.Token[len(t.Token)-8:] - t.OwnerID = a.GetID() + if t.OwnerID == 0 { + t.OwnerID = a.GetID() + } if err := PermissionsAreValid(t.APIPermissions); err != nil { return err From 3415981d1cbb6097722895cf9742808ecd16bd0b Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:58:59 +0200 Subject: [PATCH 012/313] feat(models): add BotUser CRUD wrapper --- pkg/models/bot_users.go | 133 ++++++++++++++++++++++++++++ pkg/models/bot_users_permissions.go | 56 ++++++++++++ pkg/models/bot_users_test.go | 130 +++++++++++++++++++++++++++ pkg/models/user_delete.go | 11 +++ pkg/routes/api/v1/info.go | 2 + pkg/routes/routes.go | 18 ++++ pkg/user/user.go | 2 +- 7 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 pkg/models/bot_users.go create mode 100644 pkg/models/bot_users_permissions.go create mode 100644 pkg/models/bot_users_test.go diff --git a/pkg/models/bot_users.go b/pkg/models/bot_users.go new file mode 100644 index 000000000..efc544987 --- /dev/null +++ b/pkg/models/bot_users.go @@ -0,0 +1,133 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import ( + "strings" + + "code.vikunja.io/api/pkg/user" + "code.vikunja.io/api/pkg/web" + + "xorm.io/xorm" +) + +// BotUser is a thin wrapper around user.User that implements CRUDable + Permissions +// for bot-management endpoints. Ownership lives on users.bot_owner_id, so there is +// no separate table. +type BotUser struct { + // Status shadows user.User.Status so it is included in JSON responses + // (the original has json:"-"). + Status user.Status `xorm:"-" json:"status"` + + user.User `xorm:"extends"` + + web.CRUDable `xorm:"-" json:"-"` + web.Permissions `xorm:"-" json:"-"` +} + +// Create creates a new bot user. +func (b *BotUser) Create(s *xorm.Session, a web.Auth) error { + owner, ok := a.(*user.User) + if !ok { + return ErrGenericForbidden{} + } + b.ID = 0 + created, err := user.CreateBotUser(s, &b.User, owner) + if err != nil { + return err + } + b.User = *created + b.Status = created.Status + return nil +} + +// ReadAll returns all bots owned by the calling user. +func (b *BotUser) ReadAll(s *xorm.Session, a web.Auth, search string, page int, perPage int) (result any, resultCount int, numberOfTotalItems int64, err error) { + limit, start := getLimitFromPageIndex(page, perPage) + var bots []*BotUser + q := s.Where("bot_owner_id = ?", a.GetID()) + if search != "" { + q = q.And("(username LIKE ? OR name LIKE ?)", "%"+search+"%", "%"+search+"%") + } + if limit > 0 { + q = q.Limit(limit, start) + } + total, err := q.FindAndCount(&bots) + if err != nil { + return nil, 0, 0, err + } + for _, bot := range bots { + bot.Status = bot.User.Status + } + return bots, len(bots), total, nil +} + +// ReadOne returns a single bot user. +// Ownership is verified in CanRead. +func (b *BotUser) ReadOne(s *xorm.Session, _ web.Auth) error { + u, err := user.GetUserByID(s, b.ID) + if err != nil { + return err + } + b.User = *u + b.Status = u.Status + return nil +} + +// Update allows a narrow set of fields to be changed on an owned bot. +// Ownership is verified in CanUpdate. +func (b *BotUser) Update(s *xorm.Session, _ web.Auth) error { + existing, err := user.GetUserByID(s, b.ID) + if err != nil { + return err + } + + cols := []string{"name"} + existing.Name = b.Name + + if b.Status == user.StatusDisabled { + existing.Status = b.Status + cols = append(cols, "status") + } else if b.Status == user.StatusActive && existing.Status != user.StatusActive { + existing.Status = b.Status + cols = append(cols, "status") + } + if b.Username != "" && b.Username != existing.Username { + if !strings.HasPrefix(b.Username, "bot-") { + return &user.ErrBotUsernameMustHavePrefix{Username: b.Username} + } + existing.Username = b.Username + cols = append(cols, "username") + } + + if len(cols) > 0 { + _, err = s.ID(existing.ID).Cols(cols...).Update(existing) + } + b.User = *existing + b.Status = existing.Status + return err +} + +// Delete completely removes the bot user and all associated data. +// Ownership is verified in CanDelete. +func (b *BotUser) Delete(s *xorm.Session, _ web.Auth) error { + existing, err := user.GetUserByID(s, b.ID) + if err != nil { + return err + } + return DeleteUser(s, existing) +} diff --git a/pkg/models/bot_users_permissions.go b/pkg/models/bot_users_permissions.go new file mode 100644 index 000000000..8fb4db854 --- /dev/null +++ b/pkg/models/bot_users_permissions.go @@ -0,0 +1,56 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import ( + "code.vikunja.io/api/pkg/user" + "code.vikunja.io/api/pkg/web" + + "xorm.io/xorm" +) + +// CanCreate checks if a user can create a bot user. +func (b *BotUser) CanCreate(_ *xorm.Session, a web.Auth) (bool, error) { + u, ok := a.(*user.User) + if !ok || u.IsBot() { + return false, nil + } + return true, nil +} + +// CanRead checks if a user can read a bot user. +func (b *BotUser) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) { + ok, err := b.isOwner(s, a) + return ok, 0, err +} + +// CanUpdate checks if a user can update a bot user. +func (b *BotUser) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) { return b.isOwner(s, a) } + +// CanDelete checks if a user can delete a bot user. +func (b *BotUser) CanDelete(s *xorm.Session, a web.Auth) (bool, error) { return b.isOwner(s, a) } + +func (b *BotUser) isOwner(s *xorm.Session, a web.Auth) (bool, error) { + u, err := user.GetUserByID(s, b.ID) + if err != nil { + if user.IsErrUserDoesNotExist(err) { + return false, nil + } + return false, err + } + return u.BotOwnerID == a.GetID(), nil +} diff --git a/pkg/models/bot_users_test.go b/pkg/models/bot_users_test.go new file mode 100644 index 000000000..bfb808aed --- /dev/null +++ b/pkg/models/bot_users_test.go @@ -0,0 +1,130 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import ( + "testing" + + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/user" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBotUser_Create(t *testing.T) { + t.Run("success", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := user.GetUserByID(s, 1) + require.NoError(t, err) + + bot := &BotUser{User: user.User{Username: "bot-model-success"}} + require.NoError(t, bot.Create(s, owner)) + assert.True(t, bot.IsBot()) + assert.Equal(t, owner.ID, bot.BotOwnerID) + }) + t.Run("bot cannot create bot", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwner := &user.User{ID: 555, BotOwnerID: 1} + bot := &BotUser{User: user.User{Username: "bot-child"}} + err := bot.Create(s, botOwner) + require.Error(t, err) + assert.True(t, user.IsErrBotNotOwned(err)) + }) +} + +func TestBotUser_ReadAll(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := user.GetUserByID(s, 1) + require.NoError(t, err) + + bot := &BotUser{User: user.User{Username: "bot-readall"}} + require.NoError(t, bot.Create(s, owner)) + + list := &BotUser{} + result, _, _, err := list.ReadAll(s, owner, "", 1, 50) + require.NoError(t, err) + bots, ok := result.([]*BotUser) + require.True(t, ok) + found := false + for _, u := range bots { + if u.Username == "bot-readall" { + found = true + } + } + assert.True(t, found) +} + +func TestBotUser_CanRead_NotOwned(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := user.GetUserByID(s, 1) + require.NoError(t, err) + other, err := user.GetUserByID(s, 2) + require.NoError(t, err) + + bot := &BotUser{User: user.User{Username: "bot-notowned"}} + require.NoError(t, bot.Create(s, owner)) + + view := &BotUser{User: user.User{ID: bot.ID}} + canRead, _, err := view.CanRead(s, other) + require.NoError(t, err) + assert.False(t, canRead) +} + +func TestBotUser_Update_Status(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := user.GetUserByID(s, 1) + require.NoError(t, err) + + bot := &BotUser{User: user.User{Username: "bot-update"}} + require.NoError(t, bot.Create(s, owner)) + + upd := &BotUser{Status: user.StatusDisabled, User: user.User{ID: bot.ID, Name: "Renamed"}} + require.NoError(t, upd.Update(s, owner)) + assert.Equal(t, user.StatusDisabled, upd.Status) + assert.Equal(t, "Renamed", upd.Name) +} + +func TestBotUser_Delete(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + owner, err := user.GetUserByID(s, 1) + require.NoError(t, err) + + bot := &BotUser{User: user.User{Username: "bot-delete"}} + require.NoError(t, bot.Create(s, owner)) + + del := &BotUser{User: user.User{ID: bot.ID}} + require.NoError(t, del.Delete(s, owner)) +} diff --git a/pkg/models/user_delete.go b/pkg/models/user_delete.go index 8cdba1e0d..59bd33107 100644 --- a/pkg/models/user_delete.go +++ b/pkg/models/user_delete.go @@ -128,6 +128,17 @@ func getProjectsToDelete(s *xorm.Session, u *user.User) (projectsToDelete []*Pro // This action is irrevocable. // Public to allow deletion from the CLI. func DeleteUser(s *xorm.Session, u *user.User) (err error) { + // Delete any bot users owned by this user first (cascades their data too). + var ownedBots []*user.User + if err = s.Where("bot_owner_id = ?", u.ID).Find(&ownedBots); err != nil { + return err + } + for _, bot := range ownedBots { + if err = DeleteUser(s, bot); err != nil { + return err + } + } + projectsToDelete, err := getProjectsToDelete(s, u) if err != nil { return err diff --git a/pkg/routes/api/v1/info.go b/pkg/routes/api/v1/info.go index 0f8ded367..6e7c9a6ba 100644 --- a/pkg/routes/api/v1/info.go +++ b/pkg/routes/api/v1/info.go @@ -55,6 +55,7 @@ type vikunjaInfos struct { DemoModeEnabled bool `json:"demo_mode_enabled"` WebhooksEnabled bool `json:"webhooks_enabled"` PublicTeamsEnabled bool `json:"public_teams_enabled"` + BotUsersEnabled bool `json:"bot_users_enabled"` EnabledProFeatures []license.Feature `json:"enabled_pro_features"` } @@ -107,6 +108,7 @@ func Info(c *echo.Context) error { DemoModeEnabled: config.ServiceDemoMode.GetBool(), WebhooksEnabled: config.WebhooksEnabled.GetBool(), PublicTeamsEnabled: config.ServiceEnablePublicTeams.GetBool(), + BotUsersEnabled: config.ServiceEnableBotUsers.GetBool(), EnabledProFeatures: license.EnabledProFeatures(), AvailableMigrators: []string{ (&vikunja_file.FileMigrator{}).Name(), diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index 6c52a1af5..a305c3dc6 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -481,6 +481,24 @@ func registerAPIRoutes(a *echo.Group) { u.POST("/deletion/cancel", apiv1.UserCancelDeletion) } + // Bot users + if config.ServiceEnableBotUsers.GetBool() { + botHandler := &handler.WebHandler{ + EmptyStruct: func() handler.CObject { + return &models.BotUser{} + }, + } + u.PUT("/bots", botHandler.CreateWeb) + u.GET("/bots", botHandler.ReadAllWeb) + u.GET("/bots/:bot", botHandler.ReadOneWeb) + u.POST("/bots/:bot", botHandler.UpdateWeb) + u.DELETE("/bots/:bot", botHandler.DeleteWeb) + + u.PUT("/bots/:bot/tokens", apiv1.CreateBotToken) + u.GET("/bots/:bot/tokens", apiv1.ListBotTokens) + u.DELETE("/bots/:bot/tokens/:token", apiv1.DeleteBotToken) + } + projectHandler := &handler.WebHandler{ EmptyStruct: func() handler.CObject { return &models.Project{} diff --git a/pkg/user/user.go b/pkg/user/user.go index ae2305628..eaf8b18b4 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -84,7 +84,7 @@ const ( // User holds information about an user type User struct { // The unique, numeric id of this user. - ID int64 `xorm:"bigint autoincr not null unique pk" json:"id"` + ID int64 `xorm:"bigint autoincr not null unique pk" json:"id" param:"bot"` // The full name of the user. Name string `xorm:"text null" json:"name"` // The username of the user. Is always unique. From 05acc2b6609b84765e9f706152f9cda1bbc47e92 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 20:00:15 +0200 Subject: [PATCH 013/313] feat(api): bot token support via /tokens CRUD and bot_users_enabled flag --- pkg/models/api_tokens.go | 33 ++++++++++++++++++++++++---- pkg/models/api_tokens_permissions.go | 22 +++++++++++++++---- pkg/routes/routes.go | 4 ---- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/pkg/models/api_tokens.go b/pkg/models/api_tokens.go index 80a5a10a4..ed7651b9e 100644 --- a/pkg/models/api_tokens.go +++ b/pkg/models/api_tokens.go @@ -54,7 +54,9 @@ type APIToken struct { // A timestamp when this api key was created. You cannot change this value. Created time.Time `xorm:"created not null" json:"created"` - OwnerID int64 `xorm:"bigint not null" json:"-"` + // The user ID of the token owner. When creating a token for a bot user, set this + // to the bot's ID. If omitted, defaults to the authenticated user. + OwnerID int64 `xorm:"bigint not null" json:"owner_id,omitempty"` web.Permissions `xorm:"-" json:"-"` web.CRUDable `xorm:"-" json:"-"` @@ -103,6 +105,15 @@ func (t *APIToken) Create(s *xorm.Session, a web.Auth) (err error) { if t.OwnerID == 0 { t.OwnerID = a.GetID() + } else if t.OwnerID != a.GetID() { + // If OwnerID is set to someone else, verify it's a bot owned by the caller. + botUser, err := user.GetUserByID(s, t.OwnerID) + if err != nil { + return err + } + if !botUser.IsBot() || botUser.BotOwnerID != a.GetID() { + return &user.ErrBotNotOwned{UserID: t.OwnerID} + } } if err := PermissionsAreValid(t.APIPermissions); err != nil { @@ -135,7 +146,20 @@ func (t *APIToken) ReadAll(s *xorm.Session, a web.Auth, search string, page int, tokens := []*APIToken{} - var where builder.Cond = builder.Eq{"owner_id": a.GetID()} + ownerID := a.GetID() + if t.OwnerID != 0 && t.OwnerID != a.GetID() { + // If filtering by a different owner, verify it's a bot owned by the caller. + botUser, lookupErr := user.GetUserByID(s, t.OwnerID) + if lookupErr != nil { + return nil, 0, 0, lookupErr + } + if !botUser.IsBot() || botUser.BotOwnerID != a.GetID() { + return nil, 0, 0, &user.ErrBotNotOwned{UserID: t.OwnerID} + } + ownerID = t.OwnerID + } + + var where builder.Cond = builder.Eq{"owner_id": ownerID} if search != "" { where = builder.And( @@ -168,8 +192,9 @@ func (t *APIToken) ReadAll(s *xorm.Session, a web.Auth, search string, page int, // @Failure 404 {object} web.HTTPError "The token does not exist." // @Failure 500 {object} models.Message "Internal error" // @Router /tokens/{tokenID} [delete] -func (t *APIToken) Delete(s *xorm.Session, a web.Auth) (err error) { - _, err = s.Where("id = ? AND owner_id = ?", t.ID, a.GetID()).Delete(&APIToken{}) +func (t *APIToken) Delete(s *xorm.Session, _ web.Auth) (err error) { + // Ownership is verified in CanDelete; delete by ID only. + _, err = s.Where("id = ?", t.ID).Delete(&APIToken{}) return err } diff --git a/pkg/models/api_tokens_permissions.go b/pkg/models/api_tokens_permissions.go index fb8ed0424..5d2b1b415 100644 --- a/pkg/models/api_tokens_permissions.go +++ b/pkg/models/api_tokens_permissions.go @@ -17,6 +17,7 @@ package models import ( + "code.vikunja.io/api/pkg/user" "code.vikunja.io/api/pkg/web" "xorm.io/xorm" ) @@ -27,12 +28,25 @@ func (t *APIToken) CanDelete(s *xorm.Session, a web.Auth) (bool, error) { return false, err } - if token.OwnerID != a.GetID() { - return false, nil + if token.OwnerID == a.GetID() { + *t = *token + return true, nil } - *t = *token - return true, nil + // Allow deletion if the token belongs to a bot owned by the caller. + botUser, err := user.GetUserByID(s, token.OwnerID) + if err != nil { + if user.IsErrUserDoesNotExist(err) { + return false, nil + } + return false, err + } + if botUser.IsBot() && botUser.BotOwnerID == a.GetID() { + *t = *token + return true, nil + } + + return false, nil } func (t *APIToken) CanCreate(_ *xorm.Session, _ web.Auth) (bool, error) { diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index a305c3dc6..36e8b8e3e 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -493,10 +493,6 @@ func registerAPIRoutes(a *echo.Group) { u.GET("/bots/:bot", botHandler.ReadOneWeb) u.POST("/bots/:bot", botHandler.UpdateWeb) u.DELETE("/bots/:bot", botHandler.DeleteWeb) - - u.PUT("/bots/:bot/tokens", apiv1.CreateBotToken) - u.GET("/bots/:bot/tokens", apiv1.ListBotTokens) - u.DELETE("/bots/:bot/tokens/:token", apiv1.DeleteBotToken) } projectHandler := &handler.WebHandler{ From c4e5f55b6df78c8c6f1df1a5bb60a2d25a659124 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 20:05:35 +0200 Subject: [PATCH 014/313] feat(frontend): add bot user model support and badge --- frontend/src/components/misc/User.vue | 18 ++++++++++++++++++ frontend/src/i18n/lang/en.json | 3 +++ frontend/src/modelTypes/IUser.ts | 1 + frontend/src/models/user.ts | 5 +++++ frontend/src/stores/config.ts | 2 ++ 5 files changed, 29 insertions(+) diff --git a/frontend/src/components/misc/User.vue b/frontend/src/components/misc/User.vue index 6e3820c18..5570f11d6 100644 --- a/frontend/src/components/misc/User.vue +++ b/frontend/src/components/misc/User.vue @@ -15,6 +15,10 @@ v-if="showUsername" class="username" >{{ displayName }} + {{ $t('user.bot.badge') }} @@ -36,6 +40,7 @@ const props = withDefaults(defineProps<{ }) const displayName = computed(() => getDisplayName(props.user)) +const isBot = computed(() => ((props.user as IUser & {botOwnerId?: number}).botOwnerId ?? 0) > 0) const avatarSrc = ref('') async function loadAvatar() { @@ -60,4 +65,17 @@ watch(() => [props.user, props.avatarSize], loadAvatar, { immediate: true }) vertical-align: middle; margin-inline-end: .5rem; } + +.bot-badge { + display: inline-block; + align-self: center; + margin-inline-start: .5rem; + padding: 0 .4rem; + font-size: .75rem; + line-height: 1.2; + color: var(--grey-700); + background: var(--grey-200); + border-radius: 4px; + text-transform: uppercase; +} diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json index 3b8eab1a6..07f5d376a 100644 --- a/frontend/src/i18n/lang/en.json +++ b/frontend/src/i18n/lang/en.json @@ -59,6 +59,9 @@ "text": "Please check your network connection and try again." }, "user": { + "bot": { + "badge": "Bot" + }, "auth": { "username": "Username", "usernameEmail": "Username Or Email Address", diff --git a/frontend/src/modelTypes/IUser.ts b/frontend/src/modelTypes/IUser.ts index 470ceb7ae..ae2f6ee45 100644 --- a/frontend/src/modelTypes/IUser.ts +++ b/frontend/src/modelTypes/IUser.ts @@ -24,4 +24,5 @@ export interface IUser extends IAbstract { isLocalUser: boolean deletionScheduledAt: string | Date | null isAdmin?: boolean + botOwnerId?: number } diff --git a/frontend/src/models/user.ts b/frontend/src/models/user.ts index d3cba06dd..e3fe2b128 100644 --- a/frontend/src/models/user.ts +++ b/frontend/src/models/user.ts @@ -82,6 +82,7 @@ export default class UserModel extends AbstractModel implements IUser { isLocalUser: boolean deletionScheduledAt: null isAdmin?: boolean + botOwnerId = 0 constructor(data: Partial = {}) { super() @@ -92,4 +93,8 @@ export default class UserModel extends AbstractModel implements IUser { this.settings = new UserSettingsModel(this.settings || {}) } + + get isBot(): boolean { + return (this.botOwnerId ?? 0) > 0 + } } diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts index 6ca087ff4..7784e0507 100644 --- a/frontend/src/stores/config.ts +++ b/frontend/src/stores/config.ts @@ -44,6 +44,7 @@ export interface ConfigState { }, }, publicTeamsEnabled: boolean, + botUsersEnabled: boolean, enabledProFeatures: string[], } @@ -84,6 +85,7 @@ export const useConfigStore = defineStore('config', () => { }, }, publicTeamsEnabled: false, + botUsersEnabled: false, enabledProFeatures: [], }) From d467a06e728757eb5ea75792324ecca5c333f81f Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 20:09:35 +0200 Subject: [PATCH 015/313] feat(frontend): add bot settings page and services --- frontend/src/components/misc/User.vue | 71 ++-- .../src/components/token/ApiTokenForm.vue | 402 ++++++++++++++++++ frontend/src/i18n/lang/en.json | 16 +- frontend/src/modelTypes/IApiToken.ts | 1 + frontend/src/models/apiTokenModel.ts | 1 + frontend/src/router/index.ts | 5 + frontend/src/services/botUser.ts | 19 + frontend/src/views/user/Settings.vue | 6 + .../src/views/user/settings/ApiTokens.vue | 381 ++--------------- frontend/src/views/user/settings/BotUsers.vue | 362 ++++++++++++++++ pkg/models/api_tokens.go | 2 +- 11 files changed, 885 insertions(+), 381 deletions(-) create mode 100644 frontend/src/components/token/ApiTokenForm.vue create mode 100644 frontend/src/services/botUser.ts create mode 100644 frontend/src/views/user/settings/BotUsers.vue diff --git a/frontend/src/components/misc/User.vue b/frontend/src/components/misc/User.vue index 5570f11d6..b7348b1a5 100644 --- a/frontend/src/components/misc/User.vue +++ b/frontend/src/components/misc/User.vue @@ -3,27 +3,32 @@ class="user" :class="{'is-inline': isInline}" > - + + + B + {{ displayName }} - {{ $t('user.bot.badge') }} + + diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json index 07f5d376a..8af6ae590 100644 --- a/frontend/src/i18n/lang/en.json +++ b/frontend/src/i18n/lang/en.json @@ -59,9 +59,6 @@ "text": "Please check your network connection and try again." }, "user": { - "bot": { - "badge": "Bot" - }, "auth": { "username": "Username", "usernameEmail": "Username Or Email Address", @@ -110,6 +107,19 @@ "registrationFailed": "An error occurred during registration. Please check your input and try again." }, "settings": { + "bots": { + "title": "Bot Users", + "description": "Bot users are API-only users you own. They can be added to projects, assigned tasks, and authenticated with API tokens. They cannot log in interactively.", + "namePlaceholder": "My Assistant", + "create": "Create bot", + "enable": "Enable", + "badge": "Bot", + "delete": { + "header": "Delete this bot user", + "text1": "Are you sure you want to delete the bot user \"{username}\"?", + "text2": "This is irreversible. Any API tokens belonging to this bot will be revoked." + } + }, "title": "Settings", "newPasswordTitle": "Update Your Password", "newPassword": "New password", diff --git a/frontend/src/modelTypes/IApiToken.ts b/frontend/src/modelTypes/IApiToken.ts index 189549c4d..15773df81 100644 --- a/frontend/src/modelTypes/IApiToken.ts +++ b/frontend/src/modelTypes/IApiToken.ts @@ -11,4 +11,5 @@ export interface IApiToken extends IAbstract { permissions: IApiPermission expiresAt: Date created: Date + ownerId?: number } diff --git a/frontend/src/models/apiTokenModel.ts b/frontend/src/models/apiTokenModel.ts index a23227004..096ca5f28 100644 --- a/frontend/src/models/apiTokenModel.ts +++ b/frontend/src/models/apiTokenModel.ts @@ -8,6 +8,7 @@ export default class ApiTokenModel extends AbstractModel { permissions = null expiresAt: Date = null created: Date = null + ownerId = 0 constructor(data: Partial = {}) { super() diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 23585e6f5..6d48058af 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -163,6 +163,11 @@ const router = createRouter({ name: 'user.settings.webhooks', component: () => import('@/views/user/settings/Webhooks.vue'), }, + { + path: '/user/settings/bots', + name: 'user.settings.bots', + component: () => import('@/views/user/settings/BotUsers.vue'), + }, { path: '/user/settings/migrate', name: 'migrate.start', diff --git a/frontend/src/services/botUser.ts b/frontend/src/services/botUser.ts new file mode 100644 index 000000000..6e18eef35 --- /dev/null +++ b/frontend/src/services/botUser.ts @@ -0,0 +1,19 @@ +import AbstractService from '@/services/abstractService' +import type {IUser} from '@/modelTypes/IUser' +import UserModel from '@/models/user' + +export default class BotUserService extends AbstractService { + constructor() { + super({ + create: '/user/bots', + getAll: '/user/bots', + get: '/user/bots/{id}', + update: '/user/bots/{id}', + delete: '/user/bots/{id}', + }) + } + + modelFactory(data: Partial) { + return new UserModel(data) + } +} diff --git a/frontend/src/views/user/Settings.vue b/frontend/src/views/user/Settings.vue index da9129258..9ac8688d0 100644 --- a/frontend/src/views/user/Settings.vue +++ b/frontend/src/views/user/Settings.vue @@ -26,6 +26,7 @@ const migratorsEnabled = computed(() => configStore.migratorsEnabled) const isLocalUser = computed(() => authStore.info?.isLocalUser) const userDeletionEnabled = computed(() => configStore.userDeletionEnabled) const webhooksEnabled = computed(() => configStore.webhooksEnabled) +const botUsersEnabled = computed(() => configStore.botUsersEnabled) const navigationItems = computed(() => { const items = [ @@ -80,6 +81,11 @@ const navigationItems = computed(() => { routeName: 'user.settings.webhooks', condition: webhooksEnabled.value, }, + { + title: t('user.settings.bots.title'), + routeName: 'user.settings.bots', + condition: botUsersEnabled.value, + }, { title: t('user.deletion.title'), routeName: 'user.settings.deletion', diff --git a/frontend/src/views/user/settings/ApiTokens.vue b/frontend/src/views/user/settings/ApiTokens.vue index bbbfab9cc..a9506d8e1 100644 --- a/frontend/src/views/user/settings/ApiTokens.vue +++ b/frontend/src/views/user/settings/ApiTokens.vue @@ -1,35 +1,19 @@ @@ -354,132 +141,14 @@ function toggleGroupPermissionsFromChild(group: string, checked: boolean) { -
- - - - -
- -
-
- -
- -
-
- - -
- -

{{ $t('user.settings.apiTokens.permissionExplanation') }}

- - -
- -
- - {{ $t(`user.settings.apiTokens.presets.${preset.id}`) }} - -
-
- -
- - -
-
- -

- {{ $t('user.settings.apiTokens.permissionRequired') }} -

- - {{ $t('user.settings.apiTokens.createToken') }} - - + :loading="service.loading" + :initial-title="initialTitle" + :initial-scopes="initialScopes" + @created="onTokenCreated" + @cancel="showCreateForm = false" + /> + + diff --git a/frontend/src/views/user/settings/BotUsers.vue b/frontend/src/views/user/settings/BotUsers.vue new file mode 100644 index 000000000..bb62c90e2 --- /dev/null +++ b/frontend/src/views/user/settings/BotUsers.vue @@ -0,0 +1,362 @@ + + + + + diff --git a/pkg/models/api_tokens.go b/pkg/models/api_tokens.go index ed7651b9e..3664f1b3a 100644 --- a/pkg/models/api_tokens.go +++ b/pkg/models/api_tokens.go @@ -56,7 +56,7 @@ type APIToken struct { // The user ID of the token owner. When creating a token for a bot user, set this // to the bot's ID. If omitted, defaults to the authenticated user. - OwnerID int64 `xorm:"bigint not null" json:"owner_id,omitempty"` + OwnerID int64 `xorm:"bigint not null" json:"owner_id,omitempty" query:"owner_id"` web.Permissions `xorm:"-" json:"-"` web.CRUDable `xorm:"-" json:"-"` From 999e28435e42278b55e0c3db98f9e97dc876e167 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 24 Apr 2026 11:17:52 +0200 Subject: [PATCH 016/313] feat(avatar): use distinct marble palette for bot users Bot users now render with a cool-toned (blue/cyan/violet/teal/indigo) marble variant so they're visually distinguishable from human users. Marble's rendering logic is parameterized with a palette; the route forces the bot palette whenever the resolved user is a bot, overriding whatever avatar provider they'd otherwise inherit. --- pkg/modules/avatar/avatar.go | 2 ++ pkg/modules/avatar/botmarble/botmarble.go | 44 +++++++++++++++++++++++ pkg/modules/avatar/marble/marble.go | 29 +++++++++------ pkg/routes/api/v1/avatar.go | 5 +++ 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 pkg/modules/avatar/botmarble/botmarble.go diff --git a/pkg/modules/avatar/avatar.go b/pkg/modules/avatar/avatar.go index aefb9d50f..321fb8553 100644 --- a/pkg/modules/avatar/avatar.go +++ b/pkg/modules/avatar/avatar.go @@ -18,6 +18,7 @@ package avatar import ( "code.vikunja.io/api/pkg/log" + "code.vikunja.io/api/pkg/modules/avatar/botmarble" "code.vikunja.io/api/pkg/modules/avatar/empty" "code.vikunja.io/api/pkg/modules/avatar/gravatar" "code.vikunja.io/api/pkg/modules/avatar/initials" @@ -47,6 +48,7 @@ func FlushAllCaches(u *user.User) { &ldap.Provider{}, &openid.Provider{}, &marble.Provider{}, + &botmarble.Provider{}, &empty.Provider{}, } for _, p := range providers { diff --git a/pkg/modules/avatar/botmarble/botmarble.go b/pkg/modules/avatar/botmarble/botmarble.go new file mode 100644 index 000000000..03e025ded --- /dev/null +++ b/pkg/modules/avatar/botmarble/botmarble.go @@ -0,0 +1,44 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package botmarble + +import ( + "code.vikunja.io/api/pkg/modules/avatar/marble" + "code.vikunja.io/api/pkg/user" +) + +// botColors is a cool-toned palette distinct from the marble default so bot avatars are visually recognizable as bots at a glance. +var botColors = []string{ + "#3B82F6", + "#06B6D4", + "#8B5CF6", + "#14B8A6", + "#6366F1", +} + +// Provider renders marble-style avatars using the bot-specific palette. +type Provider struct{} + +func (p *Provider) GetAvatar(u *user.User, size int64) ([]byte, string, error) { + return marble.GenerateSVG(u, size, botColors) +} + +func (p *Provider) AsDataURI(u *user.User, size int64) (string, error) { + return marble.GenerateDataURI(u, size, botColors) +} + +func (p *Provider) FlushCache(_ *user.User) error { return nil } diff --git a/pkg/modules/avatar/marble/marble.go b/pkg/modules/avatar/marble/marble.go index 2fcad6be6..9f7493253 100644 --- a/pkg/modules/avatar/marble/marble.go +++ b/pkg/modules/avatar/marble/marble.go @@ -34,7 +34,7 @@ func (p *Provider) FlushCache(_ *user.User) error { return nil } const avatarSize = 80 -var colors = []string{ +var defaultColors = []string{ "#A3A948", "#EDB92E", "#F85931", @@ -62,12 +62,12 @@ func getUnit(number int, rang, index int) int { return value } -func getPropsForUser(u *user.User) []*props { +func getPropsForUser(u *user.User, palette []string) []*props { ps := []*props{} - for i := 0; i < 3; i++ { + for i := range 3 { f := float64(getUnit(int(u.ID)*(i+1), avatarSize/10, 0)) ps = append(ps, &props{ - Color: colors[(int(u.ID)+i)%(len(colors)-1)], + Color: palette[(int(u.ID)+i)%len(palette)], TranslateX: getUnit(int(u.ID)*(i+1), avatarSize/10, 1), TranslateY: getUnit(int(u.ID)*(i+1), avatarSize/10, 2), Scale: 1.2 + f/10, @@ -78,13 +78,14 @@ func getPropsForUser(u *user.User) []*props { return ps } -func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType string, err error) { +// GenerateSVG renders a marble-style SVG avatar for the given user using the provided palette. +func GenerateSVG(u *user.User, size int64, palette []string) (avatar []byte, mimeType string, err error) { s := strconv.FormatInt(size, 10) avatarSizeStr := strconv.Itoa(avatarSize) avatarSizeHalf := strconv.Itoa(avatarSize / 2) - ps := getPropsForUser(u) + ps := getPropsForUser(u, palette) return []byte(``), "image/svg+xml", nil } -// AsDataURI returns a data URI for the SVG avatar -func (p *Provider) AsDataURI(u *user.User, size int64) (string, error) { - avatarData, mimeType, err := p.GetAvatar(u, size) +// GenerateDataURI returns a base64-encoded data URI for a marble-style SVG avatar using the provided palette. +func GenerateDataURI(u *user.User, size int64, palette []string) (string, error) { + avatarData, mimeType, err := GenerateSVG(u, size, palette) if err != nil { return "", err } - // Encode the SVG as base64 and create a data URI base64Data := base64.StdEncoding.EncodeToString(avatarData) dataURI := fmt.Sprintf("data:%s;base64,%s", mimeType, base64Data) return dataURI, nil } + +func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType string, err error) { + return GenerateSVG(u, size, defaultColors) +} + +// AsDataURI returns a data URI for the SVG avatar +func (p *Provider) AsDataURI(u *user.User, size int64) (string, error) { + return GenerateDataURI(u, size, defaultColors) +} diff --git a/pkg/routes/api/v1/avatar.go b/pkg/routes/api/v1/avatar.go index 5bddb31f5..d98b9dc32 100644 --- a/pkg/routes/api/v1/avatar.go +++ b/pkg/routes/api/v1/avatar.go @@ -22,6 +22,7 @@ import ( "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/avatar" + "code.vikunja.io/api/pkg/modules/avatar/botmarble" "code.vikunja.io/api/pkg/modules/avatar/empty" "code.vikunja.io/api/pkg/modules/avatar/upload" "code.vikunja.io/api/pkg/user" @@ -68,6 +69,10 @@ func GetAvatar(c *echo.Context) error { avatarProvider = &empty.Provider{} } + if found && u.IsBot() { + avatarProvider = &botmarble.Provider{} + } + size := c.QueryParam("size") var sizeInt int64 = 250 // Default size of 250 if size != "" { From 22d82e292b9e68b4ce701ac205da88647af6aec7 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 24 Apr 2026 11:17:32 +0200 Subject: [PATCH 017/313] feat(user): always include own bots in user search User search previously filtered bots only when they happened to match the search string. That produced two bad behaviours: 1. Bots owned by other users could surface on an exact-username match, leaking them into assignee pickers and similar UI. 2. A user could not reliably find their own bots by typing a partial name, so bots became awkward to assign to tasks. Change ListUsers to treat bot ownership explicitly: the existing match branch excludes rows owned by someone else, and a second branch always returns bots owned by the calling user. The own-bots branch also respects any AdditionalCond passed in so project-scoped listings don't start leaking bots from outside the project. --- pkg/db/fixtures/users.yml | 35 +++++++++++ pkg/models/user_list_test.go | 116 ++++++++++++++++++++++++++++++++++- pkg/user/users_project.go | 38 +++++++++++- 3 files changed, 186 insertions(+), 3 deletions(-) diff --git a/pkg/db/fixtures/users.yml b/pkg/db/fixtures/users.yml index 9e7811924..c8be6b39b 100644 --- a/pkg/db/fixtures/users.yml +++ b/pkg/db/fixtures/users.yml @@ -164,3 +164,38 @@ avatar_provider: 'openid' updated: 2018-12-02 15:13:12 created: 2018-12-01 15:13:12 +# User 21 and user 22 below are a pair of bot owners used by the user-search +# tests: user 21 has a bot (23), user 22 has a bot (24). Putting the bots on +# dedicated owners keeps the pre-existing search tests (which mostly use user1) +# unaffected. +- id: 21 + username: 'user_bot_owner_a' + password: '$2a$04$X4aRMEt0ytgPwMIgv36cI..7X9.nhY/.tYwxpqSi0ykRHx2CwQ0S6' + email: 'user_bot_owner_a@example.com' + issuer: local + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 +- id: 22 + username: 'user_bot_owner_b' + password: '$2a$04$X4aRMEt0ytgPwMIgv36cI..7X9.nhY/.tYwxpqSi0ykRHx2CwQ0S6' + email: 'user_bot_owner_b@example.com' + issuer: local + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 +# Bot owned by user 21 — used to assert own bots are always returned +# regardless of the search string. +- id: 23 + username: 'bot-owner-a-assistant' + name: 'Owner A Assistant' + issuer: local + bot_owner_id: 21 + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 +# Bot owned by user 22 — used to assert other users' bots are never leaked. +- id: 24 + username: 'bot-owner-b-assistant' + name: 'Owner B Assistant' + issuer: local + bot_owner_id: 22 + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 diff --git a/pkg/models/user_list_test.go b/pkg/models/user_list_test.go index d55e86291..7113bd113 100644 --- a/pkg/models/user_list_test.go +++ b/pkg/models/user_list_test.go @@ -58,7 +58,7 @@ func TestListUsers(t *testing.T) { all, err := user.ListAllUsers(s) require.NoError(t, err) - assert.Len(t, all, 20) + assert.Len(t, all, 24) }) t.Run("no search term", func(t *testing.T) { db.LoadAndAssertFixtures(t) @@ -171,7 +171,10 @@ func TestListUsers(t *testing.T) { MatchFuzzily: true, }) require.NoError(t, err) - assert.Len(t, all, 20) + // 22 non-bot users have "user" in their username; the two bot + // fixtures are filtered out because they don't belong to user1 + // and their usernames/names don't contain "user". + assert.Len(t, all, 22) }) // External team discoverability bypass tests @@ -239,4 +242,113 @@ func TestListUsers(t *testing.T) { // Email should be masked because the search was by name, not email assert.Empty(t, all[0].Email) }) + + // Bot visibility in user search: + // - A user's own bots are filtered by the search string (matched against + // username and name), but bypass the discoverable_by_name flag that + // hides regular users unless they opt in. + // - When no search string is provided and ReturnAllIfNoSearchProvided is + // set, own bots are returned alongside regular users. + // - Other users' bots must never leak into the results, even on an exact + // username match. + t.Run("own bot NOT returned when query does not match it", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerA := &user.User{ID: 21} + // Query string deliberately does not match the bot's username or name. + all, err := user.ListUsers(s, "user7", botOwnerA, nil) + require.NoError(t, err) + + for _, u := range all { + assert.NotEqual(t, int64(23), u.ID, "owner A's bot must not appear when the query does not match it") + } + }) + t.Run("other user's bot not returned by exact username match", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerA := &user.User{ID: 21} + // Searching for owner B's bot by its exact username must not return it. + all, err := user.ListUsers(s, "bot-owner-b-assistant", botOwnerA, nil) + require.NoError(t, err) + + for _, u := range all { + assert.NotEqual(t, int64(24), u.ID, "owner B's bot must not leak into owner A's results") + } + }) + t.Run("neither own nor other bot returned when query matches only other owner's bot", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerB := &user.User{ID: 22} + all, err := user.ListUsers(s, "bot-owner-a-assistant", botOwnerB, nil) + require.NoError(t, err) + + // Owner A's bot must not leak. Owner B's bot must not appear either since + // the query does not match its username or name. + for _, u := range all { + assert.NotEqual(t, int64(23), u.ID, "owner A's bot must not leak to owner B") + assert.NotEqual(t, int64(24), u.ID, "owner B's bot must not appear when the query does not match it") + } + }) + t.Run("own bot returned by username match", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerA := &user.User{ID: 21} + all, err := user.ListUsers(s, "bot-owner-a-assistant", botOwnerA, nil) + require.NoError(t, err) + + var foundBot bool + for _, u := range all { + if u.ID == 23 { + foundBot = true + assert.Equal(t, int64(21), u.BotOwnerID) + } + } + assert.True(t, foundBot, "owner A's bot (id=23) should appear when searching by exact username") + }) + t.Run("own bot returned by name match without discoverable_by_name", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerA := &user.User{ID: 21} + // The bot fixture does not set discoverable_by_name=true, but own bots + // should still match by name for their owner. + all, err := user.ListUsers(s, "Owner A Assistant", botOwnerA, nil) + require.NoError(t, err) + + var foundBot bool + for _, u := range all { + if u.ID == 23 { + foundBot = true + assert.Equal(t, int64(21), u.BotOwnerID) + } + } + assert.True(t, foundBot, "owner A's bot (id=23) should appear when searching by name even without discoverable_by_name") + }) + t.Run("own bot returned when no search but ReturnAllIfNoSearchProvided", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + botOwnerA := &user.User{ID: 21} + all, err := user.ListUsers(s, "", botOwnerA, &user.ProjectUserOpts{ReturnAllIfNoSearchProvided: true}) + require.NoError(t, err) + + var foundBot bool + for _, u := range all { + if u.ID == 23 { + foundBot = true + assert.Equal(t, int64(21), u.BotOwnerID) + } + } + assert.True(t, foundBot, "owner A's bot (id=23) should appear in results when no search is provided and ReturnAllIfNoSearchProvided is true") + }) } diff --git a/pkg/user/users_project.go b/pkg/user/users_project.go index 4ce88ed49..ab94a4bdf 100644 --- a/pkg/user/users_project.go +++ b/pkg/user/users_project.go @@ -147,8 +147,44 @@ func ListUsers(s *xorm.Session, search string, currentUser *User, opts *ProjectU } } + notSomeoneElsesBot := builder.Or( + builder.IsNull{"bot_owner_id"}, + builder.Eq{"bot_owner_id": 0}, + builder.Eq{"bot_owner_id": currentUser.ID}, + ) + + // Own bots: filtered by the search string when one is provided (matched + // against username and name), but bypass the discoverable_by_name flag + // regular users have. Without a search, ListUsers only returns rows when + // ReturnAllIfNoSearchProvided is set, so we surface own bots there too. + var ownBotCond builder.Cond = builder.Eq{"bot_owner_id": currentUser.ID} + if search != "" { + botSearchConds := []builder.Cond{} + for _, queryPart := range queryParts { + if opts.MatchFuzzily { + botSearchConds = append(botSearchConds, + db.ILIKE("name", queryPart), + db.ILIKE("username", queryPart), + ) + continue + } + + botSearchConds = append(botSearchConds, + db.ILIKE("username", queryPart), + db.ILIKE("name", queryPart), + ) + } + ownBotCond = builder.And( + builder.Eq{"bot_owner_id": currentUser.ID}, + builder.Or(botSearchConds...), + ) + } + err = s. - Where(cond). + Where(builder.Or( + builder.And(cond, notSomeoneElsesBot), + ownBotCond, + )). OrderBy("id"). Find(&users) From 0adf85dc2d1a9ba89e9f1613226ce300c85d5103 Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Fri, 1 May 2026 15:01:51 +0000 Subject: [PATCH 018/313] [skip ci] Updated swagger docs --- pkg/swagger/docs.go | 27 +++++++++++++++++++++++++++ pkg/swagger/swagger.json | 27 +++++++++++++++++++++++++++ pkg/swagger/swagger.yaml | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index dd526292a..8af387674 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -8995,6 +8995,10 @@ const docTemplate = `{ "auth_provider": { "type": "string" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -9345,6 +9349,10 @@ const docTemplate = `{ "description": "The unique, numeric id of this api key.", "type": "integer" }, + "owner_id": { + "description": "The user ID of the token owner. When creating a token for a bot user, set this\nto the bot's ID. If omitted, defaults to the authenticated user.", + "type": "integer" + }, "permissions": { "description": "The permissions this token has. Possible values are available via the /routes endpoint and consist of the keys of the list from that endpoint. For example, if the token should be able to read all tasks as well as update existing tasks, you should add ` + "`" + `{\"tasks\":[\"read_all\",\"update\"]}` + "`" + `.", "allOf": [ @@ -10531,6 +10539,10 @@ const docTemplate = `{ "description": "Whether the member is an admin of the team. See the docs for more about what a team admin can do", "type": "boolean" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -10621,6 +10633,10 @@ const docTemplate = `{ "models.UserWithPermission": { "type": "object", "properties": { + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -10889,6 +10905,10 @@ const docTemplate = `{ "user.User": { "type": "object", "properties": { + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -11066,6 +11086,10 @@ const docTemplate = `{ "auth_provider": { "type": "string" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -11177,6 +11201,9 @@ const docTemplate = `{ "type": "string" } }, + "bot_users_enabled": { + "type": "boolean" + }, "caldav_enabled": { "type": "boolean" }, diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index 270d5343c..f58832190 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -8987,6 +8987,10 @@ "auth_provider": { "type": "string" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -9337,6 +9341,10 @@ "description": "The unique, numeric id of this api key.", "type": "integer" }, + "owner_id": { + "description": "The user ID of the token owner. When creating a token for a bot user, set this\nto the bot's ID. If omitted, defaults to the authenticated user.", + "type": "integer" + }, "permissions": { "description": "The permissions this token has. Possible values are available via the /routes endpoint and consist of the keys of the list from that endpoint. For example, if the token should be able to read all tasks as well as update existing tasks, you should add `{\"tasks\":[\"read_all\",\"update\"]}`.", "allOf": [ @@ -10523,6 +10531,10 @@ "description": "Whether the member is an admin of the team. See the docs for more about what a team admin can do", "type": "boolean" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -10613,6 +10625,10 @@ "models.UserWithPermission": { "type": "object", "properties": { + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -10881,6 +10897,10 @@ "user.User": { "type": "object", "properties": { + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -11058,6 +11078,10 @@ "auth_provider": { "type": "string" }, + "bot_owner_id": { + "description": "BotOwnerID is the ID of the owning (human) user if this user is a bot.\nA non-zero value means this user is a bot and cannot authenticate via password.", + "type": "integer" + }, "created": { "description": "A timestamp when this task was created. You cannot change this value.", "type": "string" @@ -11169,6 +11193,9 @@ "type": "string" } }, + "bot_users_enabled": { + "type": "boolean" + }, "caldav_enabled": { "type": "boolean" }, diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index 6d0b62a65..f186de3f1 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -82,6 +82,11 @@ definitions: properties: auth_provider: type: string + bot_owner_id: + description: |- + BotOwnerID is the ID of the owning (human) user if this user is a bot. + A non-zero value means this user is a bot and cannot authenticate via password. + type: integer created: description: A timestamp when this task was created. You cannot change this value. @@ -328,6 +333,11 @@ definitions: id: description: The unique, numeric id of this api key. type: integer + owner_id: + description: |- + The user ID of the token owner. When creating a token for a bot user, set this + to the bot's ID. If omitted, defaults to the authenticated user. + type: integer permissions: allOf: - $ref: '#/definitions/models.APIPermissions' @@ -1247,6 +1257,11 @@ definitions: description: Whether the member is an admin of the team. See the docs for more about what a team admin can do type: boolean + bot_owner_id: + description: |- + BotOwnerID is the ID of the owning (human) user if this user is a bot. + A non-zero value means this user is a bot and cannot authenticate via password. + type: integer created: description: A timestamp when this task was created. You cannot change this value. @@ -1318,6 +1333,11 @@ definitions: type: object models.UserWithPermission: properties: + bot_owner_id: + description: |- + BotOwnerID is the ID of the owning (human) user if this user is a bot. + A non-zero value means this user is a bot and cannot authenticate via password. + type: integer created: description: A timestamp when this task was created. You cannot change this value. @@ -1520,6 +1540,11 @@ definitions: type: object user.User: properties: + bot_owner_id: + description: |- + BotOwnerID is the ID of the owning (human) user if this user is a bot. + A non-zero value means this user is a bot and cannot authenticate via password. + type: integer created: description: A timestamp when this task was created. You cannot change this value. @@ -1664,6 +1689,11 @@ definitions: properties: auth_provider: type: string + bot_owner_id: + description: |- + BotOwnerID is the ID of the owning (human) user if this user is a bot. + A non-zero value means this user is a bot and cannot authenticate via password. + type: integer created: description: A timestamp when this task was created. You cannot change this value. @@ -1741,6 +1771,8 @@ definitions: items: type: string type: array + bot_users_enabled: + type: boolean caldav_enabled: type: boolean demo_mode_enabled: From 935c950942326ace74bfd9dc6cf9dfdcdd52af10 Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Mon, 4 May 2026 01:56:28 +0000 Subject: [PATCH 019/313] chore(i18n): update translations via Crowdin --- frontend/src/i18n/lang/fi-FI.json | 3 +++ frontend/src/i18n/lang/uk-UA.json | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/frontend/src/i18n/lang/fi-FI.json b/frontend/src/i18n/lang/fi-FI.json index 4dcccd211..5ceb0be11 100644 --- a/frontend/src/i18n/lang/fi-FI.json +++ b/frontend/src/i18n/lang/fi-FI.json @@ -6,6 +6,9 @@ "home": { "welcomeNight": "Hyvää Yötä {username}!", "welcomeMorning": "Hyvää Huomenta {username}!", + "welcomeMorningBack": "Tervetuloa takaisin, {username}", + "welcomeTuesday": "Hyvää tiistaita, {username}", + "welcomeWednesdayMid": "On jo keskiviikko, {username}", "welcomeDay": "Moi {username}!", "welcomeEvening": "Hyvää Iltaa {username}!", "lastViewed": "Viimeksi katsottu", diff --git a/frontend/src/i18n/lang/uk-UA.json b/frontend/src/i18n/lang/uk-UA.json index a035ec431..c47f4007e 100644 --- a/frontend/src/i18n/lang/uk-UA.json +++ b/frontend/src/i18n/lang/uk-UA.json @@ -107,6 +107,19 @@ "registrationFailed": "Ой, щось пішло не так при реєстрації. Перевірте, чи все заповнено правильно, і спробуйте знову." }, "settings": { + "bots": { + "title": "Користувачі-боти", + "description": "Користувачі-боти — це облікові записи лише для API, якими ви володієте. Їх можна додавати до проєктів, призначати на завдання та автентифікувати за допомогою API-токенів. Вони не можуть входити в систему через інтерфейс.", + "namePlaceholder": "Мій асистент", + "create": "Створити бота", + "enable": "Увімкнути", + "badge": "Бот", + "delete": { + "header": "Видалити цього бота", + "text1": "Ви впевнені, що хочете видалити користувача-бота \"{username}\"?", + "text2": "Цю дію неможливо скасувати. Усі API-токени, що належать цьому боту, буде відкликано." + } + }, "title": "Налаштування", "newPasswordTitle": "Зміна паролю", "newPassword": "Новий пароль", From 0f1bf6fab266c098c5aef25763c02368129c5f62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 06:32:19 +0000 Subject: [PATCH 020/313] chore(deps): update dev-dependencies --- desktop/package.json | 2 +- desktop/pnpm-lock.yaml | 10 +- frontend/package.json | 14 +- frontend/pnpm-lock.yaml | 838 ++++++++++++++++++++-------------------- 4 files changed, 426 insertions(+), 438 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index b7261093d..e60798ba7 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -61,7 +61,7 @@ } }, "devDependencies": { - "electron": "40.9.2", + "electron": "40.9.3", "electron-builder": "26.8.1", "unzipper": "0.12.3" }, diff --git a/desktop/pnpm-lock.yaml b/desktop/pnpm-lock.yaml index c3d9f0845..488330fa4 100644 --- a/desktop/pnpm-lock.yaml +++ b/desktop/pnpm-lock.yaml @@ -19,8 +19,8 @@ importers: version: 5.2.1 devDependencies: electron: - specifier: 40.9.2 - version: 40.9.2 + specifier: 40.9.3 + version: 40.9.3 electron-builder: specifier: 26.8.1 version: 26.8.1(electron-builder-squirrel-windows@24.13.3) @@ -560,8 +560,8 @@ packages: electron-publish@26.8.1: resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} - electron@40.9.2: - resolution: {integrity: sha512-gTLLTlfMyORZDj+03tkxsstQOQlmu6dYl0X8cwlmFb+gMmCM9Gc+rmBGSaCb5KI11IMUWHu4hvKA/spP8oJe+w==} + electron@40.9.3: + resolution: {integrity: sha512-rDcJOT6BBE689Ada+4jD3rVr05pMv9MZOgT0x/rIMVDF9c4ttx4RTb6lVARTyxZC7uqpirttCtcli1eg1DX5qg==} engines: {node: '>= 12.20.55'} hasBin: true @@ -2364,7 +2364,7 @@ snapshots: transitivePeerDependencies: - supports-color - electron@40.9.2: + electron@40.9.3: dependencies: '@electron/get': 2.0.3 '@types/node': 24.10.9 diff --git a/frontend/package.json b/frontend/package.json index ca2b2b920..2ed07c490 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -116,16 +116,16 @@ "@types/node": "24.12.2", "@types/sortablejs": "1.15.9", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.59.0", - "@typescript-eslint/parser": "8.59.0", + "@typescript-eslint/eslint-plugin": "8.59.1", + "@typescript-eslint/parser": "8.59.1", "@vitejs/plugin-vue": "6.0.6", "@vue/eslint-config-typescript": "14.7.0", - "@vue/test-utils": "2.4.7", + "@vue/test-utils": "2.4.10", "@vue/tsconfig": "0.9.1", - "@vueuse/shared": "14.2.1", + "@vueuse/shared": "14.3.0", "autoprefixer": "10.5.0", "browserslist": "4.28.2", - "caniuse-lite": "1.0.30001790", + "caniuse-lite": "1.0.30001791", "csstype": "3.2.3", "esbuild": "0.28.0", "eslint": "9.39.4", @@ -134,14 +134,14 @@ "happy-dom": "20.9.0", "histoire": "1.0.0-beta.1", "otplib": "12.0.1", - "postcss": "8.5.10", + "postcss": "8.5.13", "postcss-easing-gradients": "3.0.1", "postcss-html": "1.8.1", "postcss-preset-env": "11.2.1", "rollup": "4.60.2", "rollup-plugin-visualizer": "6.0.11", "sass-embedded": "1.99.0", - "stylelint": "17.9.0", + "stylelint": "17.9.1", "stylelint-config-property-sort-order-smacss": "10.0.0", "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index ea280a171..2da3fe358 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -206,35 +206,35 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.59.0 - version: 8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.1 + version: 8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.59.0 - version: 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.1 + version: 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.6 version: 6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': - specifier: 2.4.7 - version: 2.4.7(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) + specifier: 2.4.10 + version: 2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) '@vue/tsconfig': specifier: 0.9.1 version: 0.9.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)) '@vueuse/shared': - specifier: 14.2.1 - version: 14.2.1(vue@3.5.27(typescript@5.9.3)) + specifier: 14.3.0 + version: 14.3.0(vue@3.5.27(typescript@5.9.3)) autoprefixer: specifier: 10.5.0 - version: 10.5.0(postcss@8.5.10) + version: 10.5.0(postcss@8.5.13) browserslist: specifier: 4.28.2 version: 4.28.2 caniuse-lite: - specifier: 1.0.30001790 - version: 1.0.30001790 + specifier: 1.0.30001791 + version: 1.0.30001791 csstype: specifier: 3.2.3 version: 3.2.3 @@ -249,7 +249,7 @@ importers: version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: specifier: 10.9.0 - version: 10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + version: 10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: specifier: 20.9.0 version: 20.9.0 @@ -260,8 +260,8 @@ importers: specifier: 12.0.1 version: 12.0.1 postcss: - specifier: 8.5.10 - version: 8.5.10 + specifier: 8.5.13 + version: 8.5.13 postcss-easing-gradients: specifier: 3.0.1 version: 3.0.1 @@ -270,7 +270,7 @@ importers: version: 1.8.1 postcss-preset-env: specifier: 11.2.1 - version: 11.2.1(postcss@8.5.10) + version: 11.2.1(postcss@8.5.13) rollup: specifier: 4.60.2 version: 4.60.2 @@ -281,20 +281,20 @@ importers: specifier: 1.99.0 version: 1.99.0 stylelint: - specifier: 17.9.0 - version: 17.9.0(typescript@5.9.3) + specifier: 17.9.1 + version: 17.9.1(typescript@5.9.3) stylelint-config-property-sort-order-smacss: specifier: 10.0.0 - version: 10.0.0(stylelint@17.9.0(typescript@5.9.3)) + version: 10.0.0(stylelint@17.9.1(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: 1.6.1 - version: 1.6.1(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 - version: 2.1.3(stylelint@17.9.0(typescript@5.9.3)) + version: 2.1.3(stylelint@17.9.1(typescript@5.9.3)) tailwindcss: specifier: 4.2.4 version: 4.2.4 @@ -973,14 +973,6 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.2': - resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==} - peerDependencies: - css-tree: ^3.2.1 - peerDependenciesMeta: - css-tree: - optional: true - '@csstools/css-syntax-patches-for-csstree@1.1.3': resolution: {integrity: sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==} peerDependencies: @@ -2863,11 +2855,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.59.0': - resolution: {integrity: sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==} + '@typescript-eslint/eslint-plugin@8.59.1': + resolution: {integrity: sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.0 + '@typescript-eslint/parser': ^8.59.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -2878,8 +2870,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.59.0': - resolution: {integrity: sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==} + '@typescript-eslint/parser@8.59.1': + resolution: {integrity: sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2897,8 +2889,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.0': - resolution: {integrity: sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==} + '@typescript-eslint/project-service@8.59.1': + resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2911,8 +2903,8 @@ packages: resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.0': - resolution: {integrity: sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==} + '@typescript-eslint/scope-manager@8.59.1': + resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.56.0': @@ -2927,14 +2919,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.58.2': - resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} + '@typescript-eslint/tsconfig-utils@8.59.0': + resolution: {integrity: sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.0': - resolution: {integrity: sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==} + '@typescript-eslint/tsconfig-utils@8.59.1': + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2946,8 +2938,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.59.0': - resolution: {integrity: sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==} + '@typescript-eslint/type-utils@8.59.1': + resolution: {integrity: sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2961,14 +2953,14 @@ packages: resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.58.2': - resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.0': resolution: {integrity: sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.1': + resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.0': resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2981,8 +2973,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/typescript-estree@8.59.0': - resolution: {integrity: sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==} + '@typescript-eslint/typescript-estree@8.59.1': + resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -3001,8 +2993,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.0': - resolution: {integrity: sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==} + '@typescript-eslint/utils@8.59.1': + resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3016,8 +3008,8 @@ packages: resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.0': - resolution: {integrity: sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==} + '@typescript-eslint/visitor-keys@8.59.1': + resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -3150,8 +3142,8 @@ packages: '@vue/shared@3.5.27': resolution: {integrity: sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==} - '@vue/test-utils@2.4.7': - resolution: {integrity: sha512-tyIgzH/BdAjZsgKlFrytTW515CpduI5uzoCwa0r0ftwZTBTCX5sSIERsbYEjj+6vnp4/EYyW0Qb6ASI4jfgptg==} + '@vue/test-utils@2.4.10': + resolution: {integrity: sha512-SmoZ5EA1kYiAFs9NkYdiFFQF+cSnUwnvlYEbY+DogWQZUiqOm/Y29eSbc5T6yi75SgSF9863SBeXniIEoPajCA==} peerDependencies: '@vue/compiler-dom': 3.x '@vue/server-renderer': 3.x @@ -3190,8 +3182,8 @@ packages: peerDependencies: vue: ^3.5.0 - '@vueuse/shared@14.2.1': - resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} + '@vueuse/shared@14.3.0': + resolution: {integrity: sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==} peerDependencies: vue: ^3.5.0 @@ -3469,8 +3461,8 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001790: - resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} + caniuse-lite@1.0.30001791: + resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} capture-website@4.2.0: resolution: {integrity: sha512-EmkSn36CXTC8tUsS6aNmvvsdpfVTYYkuRp7U5bV9gcJwcDbqqA5c0Op/iskYPKtDdOkuVp61mjn/LLywX0h7cw==} @@ -5527,8 +5519,8 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.5.10: - resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} + postcss@8.5.13: + resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -6251,8 +6243,8 @@ packages: peerDependencies: stylelint: '>= 11 < 18' - stylelint@17.9.0: - resolution: {integrity: sha512-xO0jeY6z1/urFL5L/BZLmB1yYlbRiRMQnYH6ArZIDWJ+SZXGssOY7XoYb1JIv/L220+EBnwwJXJS4Mt/F96SvA==} + stylelint@17.9.1: + resolution: {integrity: sha512-THTmnAPJTrg/JhkTWZlSyrO+HUYMx6ELthIHeMyD2WOKqXIJUFQv2Yxn91bvUrZdbBJaW2dUuQdPST2wcQ6C3g==} engines: {node: '>=20.19.0'} hasBin: true @@ -7880,10 +7872,6 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)': - optionalDependencies: - css-tree: 3.2.1 - '@csstools/css-syntax-patches-for-csstree@1.1.3(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -7897,283 +7885,283 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.10)': + '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.10)': + '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.13)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.10)': + '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-color-function@5.0.3(postcss@8.5.10)': + '@csstools/postcss-color-function@5.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.10)': + '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.10)': + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.10)': + '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.10)': + '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.10)': + '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.10)': + '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.13)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.10)': + '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.13)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.10)': + '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.10)': + '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.10)': + '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.10)': + '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.13)': dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-initial@3.0.0(postcss@8.5.10)': + '@csstools/postcss-initial@3.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.10)': + '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.13)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.10)': + '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.10)': + '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.10)': + '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.10)': + '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.10)': + '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.10)': + '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.13)': dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.10)': + '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.10)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-mixins@1.0.0(postcss@8.5.10)': + '@csstools/postcss-mixins@1.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.10)': + '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.13)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.10)': + '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.10)': + '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.10)': + '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.10)': + '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.10)': + '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-random-function@3.0.2(postcss@8.5.10)': + '@csstools/postcss-random-function@3.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.10)': + '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.13)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.10)': + '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.10)': + '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.10)': + '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.10)': + '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.13)': dependencies: '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.10)': + '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.13)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.10)': + '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.13)': dependencies: '@csstools/color-helpers': 6.0.2 - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.10)': + '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.13)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 - '@csstools/postcss-unset-value@5.0.0(postcss@8.5.10)': + '@csstools/postcss-unset-value@5.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 '@csstools/selector-resolve-nested@4.0.0(postcss-selector-parser@7.1.1)': dependencies: @@ -8183,9 +8171,9 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 - '@csstools/utilities@3.0.0(postcss@8.5.10)': + '@csstools/utilities@3.0.0(postcss@8.5.13)': dependencies: - postcss: 8.5.10 + postcss: 8.5.13 '@esbuild/aix-ppc64@0.25.12': optional: true @@ -9540,14 +9528,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/type-utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/type-utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.1 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9568,12 +9556,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.1 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 @@ -9582,8 +9570,8 @@ snapshots: '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) - '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) + '@typescript-eslint/types': 8.59.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9591,17 +9579,17 @@ snapshots: '@typescript-eslint/project-service@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) - '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) + '@typescript-eslint/types': 8.59.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.59.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9617,10 +9605,10 @@ snapshots: '@typescript-eslint/types': 8.58.0 '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/scope-manager@8.59.0': + '@typescript-eslint/scope-manager@8.59.1': dependencies: - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: @@ -9630,11 +9618,11 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.58.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -9650,11 +9638,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -9666,10 +9654,10 @@ snapshots: '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/types@8.58.2': {} - '@typescript-eslint/types@8.59.0': {} + '@typescript-eslint/types@8.59.1': {} + '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) @@ -9700,12 +9688,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.59.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.59.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/project-service': 8.59.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.3 @@ -9737,12 +9725,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9758,9 +9746,9 @@ snapshots: '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.0 - '@typescript-eslint/visitor-keys@8.59.0': + '@typescript-eslint/visitor-keys@8.59.1': dependencies: - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/types': 8.59.1 eslint-visitor-keys: 5.0.0 '@ungap/structured-clone@1.3.0': {} @@ -9876,7 +9864,7 @@ snapshots: '@vue/shared': 3.5.27 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.10 + postcss: 8.5.13 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.27': @@ -9919,11 +9907,11 @@ snapshots: '@vue/devtools-shared@8.1.1': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) @@ -9966,7 +9954,7 @@ snapshots: '@vue/shared@3.5.27': {} - '@vue/test-utils@2.4.7(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': + '@vue/test-utils@2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: '@vue/compiler-dom': 3.5.27 js-beautify: 1.15.1 @@ -9999,7 +9987,7 @@ snapshots: dependencies: vue: 3.5.27(typescript@5.9.3) - '@vueuse/shared@14.2.1(vue@3.5.27(typescript@5.9.3))': + '@vueuse/shared@14.3.0(vue@3.5.27(typescript@5.9.3))': dependencies: vue: 3.5.27(typescript@5.9.3) @@ -10101,13 +10089,13 @@ snapshots: stubborn-fs: 2.0.0 when-exit: 2.1.5 - autoprefixer@10.5.0(postcss@8.5.10): + autoprefixer@10.5.0(postcss@8.5.13): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001790 + caniuse-lite: 1.0.30001791 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -10223,7 +10211,7 @@ snapshots: browserslist@4.28.2: dependencies: baseline-browser-mapping: 2.10.12 - caniuse-lite: 1.0.30001790 + caniuse-lite: 1.0.30001791 electron-to-chromium: 1.5.329 node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -10285,7 +10273,7 @@ snapshots: camelcase@8.0.0: {} - caniuse-lite@1.0.30001790: {} + caniuse-lite@1.0.30001791: {} capture-website@4.2.0(typescript@5.9.3): dependencies: @@ -10437,23 +10425,23 @@ snapshots: crypto-random-string@2.0.0: {} - css-blank-pseudo@8.0.1(postcss@8.5.10): + css-blank-pseudo@8.0.1(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 css-functions-list@3.3.3: {} - css-has-pseudo@8.0.0(postcss@8.5.10): + css-has-pseudo@8.0.0(postcss@8.5.13): dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - css-prefers-color-scheme@11.0.0(postcss@8.5.10): + css-prefers-color-scheme@11.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 css-property-sort-order-smacss@2.2.0: {} @@ -10493,7 +10481,7 @@ snapshots: cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 - '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.3(css-tree@3.2.1) css-tree: 3.2.1 lru-cache: 11.2.4 @@ -10881,7 +10869,7 @@ snapshots: module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): + eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) eslint: 9.39.4(jiti@2.6.1) @@ -10892,7 +10880,7 @@ snapshots: vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: @@ -12252,72 +12240,72 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-attribute-case-insensitive@8.0.0(postcss@8.5.10): + postcss-attribute-case-insensitive@8.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-clamp@4.1.0(postcss@8.5.10): + postcss-clamp@4.1.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@8.0.3(postcss@8.5.10): + postcss-color-functional-notation@8.0.3(postcss@8.5.13): dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - postcss-color-hex-alpha@11.0.0(postcss@8.5.10): + postcss-color-hex-alpha@11.0.0(postcss@8.5.13): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@11.0.0(postcss@8.5.10): + postcss-color-rebeccapurple@11.0.0(postcss@8.5.13): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-custom-media@12.0.1(postcss@8.5.10): + postcss-custom-media@12.0.1(postcss@8.5.13): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.10 + postcss: 8.5.13 - postcss-custom-properties@15.0.1(postcss@8.5.10): + postcss-custom-properties@15.0.1(postcss@8.5.13): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-custom-selectors@9.0.1(postcss@8.5.10): + postcss-custom-selectors@9.0.1(postcss@8.5.13): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-dir-pseudo-class@10.0.0(postcss@8.5.10): + postcss-dir-pseudo-class@10.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-double-position-gradients@7.0.0(postcss@8.5.10): + postcss-double-position-gradients@7.0.0(postcss@8.5.13): dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 postcss-easing-gradients@3.0.1: @@ -12327,181 +12315,181 @@ snapshots: postcss: 7.0.39 postcss-value-parser: 3.3.1 - postcss-focus-visible@11.0.0(postcss@8.5.10): + postcss-focus-visible@11.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-focus-within@10.0.0(postcss@8.5.10): + postcss-focus-within@10.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-font-variant@5.0.0(postcss@8.5.10): + postcss-font-variant@5.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-gap-properties@7.0.0(postcss@8.5.10): + postcss-gap-properties@7.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-html@1.8.1: dependencies: htmlparser2: 8.0.2 js-tokens: 9.0.1 - postcss: 8.5.10 - postcss-safe-parser: 6.0.0(postcss@8.5.10) + postcss: 8.5.13 + postcss-safe-parser: 6.0.0(postcss@8.5.13) - postcss-image-set-function@8.0.0(postcss@8.5.10): + postcss-image-set-function@8.0.0(postcss@8.5.13): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-lab-function@8.0.3(postcss@8.5.10): + postcss-lab-function@8.0.3(postcss@8.5.13): dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/utilities': 3.0.0(postcss@8.5.10) - postcss: 8.5.10 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/utilities': 3.0.0(postcss@8.5.13) + postcss: 8.5.13 - postcss-logical@9.0.0(postcss@8.5.10): + postcss-logical@9.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 postcss-media-query-parser@0.2.3: {} - postcss-nesting@14.0.0(postcss@8.5.10): + postcss-nesting@14.0.0(postcss@8.5.13): dependencies: '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-opacity-percentage@3.0.0(postcss@8.5.10): + postcss-opacity-percentage@3.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-overflow-shorthand@7.0.0(postcss@8.5.10): + postcss-overflow-shorthand@7.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.10): + postcss-page-break@3.0.4(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-place@11.0.0(postcss@8.5.10): + postcss-place@11.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser: 4.2.0 - postcss-preset-env@11.2.1(postcss@8.5.10): + postcss-preset-env@11.2.1(postcss@8.5.13): dependencies: - '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.10) - '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.10) - '@csstools/postcss-color-function': 5.0.3(postcss@8.5.10) - '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.10) - '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.10) - '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.10) - '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.10) - '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.10) - '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.10) - '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.10) - '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.10) - '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.10) - '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.10) - '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.10) - '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.10) - '@csstools/postcss-initial': 3.0.0(postcss@8.5.10) - '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.10) - '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.10) - '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.10) - '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.10) - '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.10) - '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.10) - '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.10) - '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.10) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.10) - '@csstools/postcss-mixins': 1.0.0(postcss@8.5.10) - '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.10) - '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.10) - '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.10) - '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.10) - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) - '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.10) - '@csstools/postcss-random-function': 3.0.2(postcss@8.5.10) - '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.10) - '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.10) - '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.10) - '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.10) - '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.10) - '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.10) - '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.10) - '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.10) - '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.10) - autoprefixer: 10.5.0(postcss@8.5.10) + '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.13) + '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.13) + '@csstools/postcss-color-function': 5.0.3(postcss@8.5.13) + '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.13) + '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.13) + '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.13) + '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.13) + '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.13) + '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.13) + '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.13) + '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.13) + '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.13) + '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.13) + '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.13) + '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.13) + '@csstools/postcss-initial': 3.0.0(postcss@8.5.13) + '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.13) + '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.13) + '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.13) + '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.13) + '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.13) + '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.13) + '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.13) + '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.13) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.13) + '@csstools/postcss-mixins': 1.0.0(postcss@8.5.13) + '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.13) + '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.13) + '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.13) + '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.13) + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) + '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.13) + '@csstools/postcss-random-function': 3.0.2(postcss@8.5.13) + '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.13) + '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.13) + '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.13) + '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.13) + '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.13) + '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.13) + '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.13) + '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.13) + '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.13) + autoprefixer: 10.5.0(postcss@8.5.13) browserslist: 4.28.2 - css-blank-pseudo: 8.0.1(postcss@8.5.10) - css-has-pseudo: 8.0.0(postcss@8.5.10) - css-prefers-color-scheme: 11.0.0(postcss@8.5.10) + css-blank-pseudo: 8.0.1(postcss@8.5.13) + css-has-pseudo: 8.0.0(postcss@8.5.13) + css-prefers-color-scheme: 11.0.0(postcss@8.5.13) cssdb: 8.8.0 - postcss: 8.5.10 - postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.10) - postcss-clamp: 4.1.0(postcss@8.5.10) - postcss-color-functional-notation: 8.0.3(postcss@8.5.10) - postcss-color-hex-alpha: 11.0.0(postcss@8.5.10) - postcss-color-rebeccapurple: 11.0.0(postcss@8.5.10) - postcss-custom-media: 12.0.1(postcss@8.5.10) - postcss-custom-properties: 15.0.1(postcss@8.5.10) - postcss-custom-selectors: 9.0.1(postcss@8.5.10) - postcss-dir-pseudo-class: 10.0.0(postcss@8.5.10) - postcss-double-position-gradients: 7.0.0(postcss@8.5.10) - postcss-focus-visible: 11.0.0(postcss@8.5.10) - postcss-focus-within: 10.0.0(postcss@8.5.10) - postcss-font-variant: 5.0.0(postcss@8.5.10) - postcss-gap-properties: 7.0.0(postcss@8.5.10) - postcss-image-set-function: 8.0.0(postcss@8.5.10) - postcss-lab-function: 8.0.3(postcss@8.5.10) - postcss-logical: 9.0.0(postcss@8.5.10) - postcss-nesting: 14.0.0(postcss@8.5.10) - postcss-opacity-percentage: 3.0.0(postcss@8.5.10) - postcss-overflow-shorthand: 7.0.0(postcss@8.5.10) - postcss-page-break: 3.0.4(postcss@8.5.10) - postcss-place: 11.0.0(postcss@8.5.10) - postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.10) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.10) - postcss-selector-not: 9.0.0(postcss@8.5.10) + postcss: 8.5.13 + postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.13) + postcss-clamp: 4.1.0(postcss@8.5.13) + postcss-color-functional-notation: 8.0.3(postcss@8.5.13) + postcss-color-hex-alpha: 11.0.0(postcss@8.5.13) + postcss-color-rebeccapurple: 11.0.0(postcss@8.5.13) + postcss-custom-media: 12.0.1(postcss@8.5.13) + postcss-custom-properties: 15.0.1(postcss@8.5.13) + postcss-custom-selectors: 9.0.1(postcss@8.5.13) + postcss-dir-pseudo-class: 10.0.0(postcss@8.5.13) + postcss-double-position-gradients: 7.0.0(postcss@8.5.13) + postcss-focus-visible: 11.0.0(postcss@8.5.13) + postcss-focus-within: 10.0.0(postcss@8.5.13) + postcss-font-variant: 5.0.0(postcss@8.5.13) + postcss-gap-properties: 7.0.0(postcss@8.5.13) + postcss-image-set-function: 8.0.0(postcss@8.5.13) + postcss-lab-function: 8.0.3(postcss@8.5.13) + postcss-logical: 9.0.0(postcss@8.5.13) + postcss-nesting: 14.0.0(postcss@8.5.13) + postcss-opacity-percentage: 3.0.0(postcss@8.5.13) + postcss-overflow-shorthand: 7.0.0(postcss@8.5.13) + postcss-page-break: 3.0.4(postcss@8.5.13) + postcss-place: 11.0.0(postcss@8.5.13) + postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.13) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.13) + postcss-selector-not: 9.0.0(postcss@8.5.13) - postcss-pseudo-class-any-link@11.0.0(postcss@8.5.10): + postcss-pseudo-class-any-link@11.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.10): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@6.0.0(postcss@8.5.10): + postcss-safe-parser@6.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-safe-parser@7.0.1(postcss@8.5.10): + postcss-safe-parser@7.0.1(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-scss@4.0.9(postcss@8.5.10): + postcss-scss@4.0.9(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 - postcss-selector-not@9.0.0(postcss@8.5.10): + postcss-selector-not@9.0.0(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-selector-parser: 7.1.1 postcss-selector-parser@7.1.1: @@ -12509,9 +12497,9 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sorting@8.0.2(postcss@8.5.10): + postcss-sorting@8.0.2(postcss@8.5.13): dependencies: - postcss: 8.5.10 + postcss: 8.5.13 postcss-value-parser@3.3.1: {} @@ -12522,7 +12510,7 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.5.10: + postcss@8.5.13: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -13272,58 +13260,58 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 - stylelint: 17.9.0(typescript@5.9.3) + stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.9.1(typescript@5.9.3)): dependencies: css-property-sort-order-smacss: 2.2.0 - stylelint: 17.9.0(typescript@5.9.3) - stylelint-order: 6.0.4(stylelint@17.9.0(typescript@5.9.3)) + stylelint: 17.9.1(typescript@5.9.3) + stylelint-order: 6.0.4(stylelint@17.9.1(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.5.10) - stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) - stylelint-scss: 7.0.0(stylelint@17.9.0(typescript@5.9.3)) + postcss-scss: 4.0.9(postcss@8.5.13) + stylelint: 17.9.1(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) + stylelint-scss: 7.0.0(stylelint@17.9.1(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.10 + postcss: 8.5.13 - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 semver: 7.7.3 - stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)) - stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) + stylelint: 17.9.1(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) - stylelint-config-recommended@18.0.0(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.9.1(typescript@5.9.3)): dependencies: - stylelint: 17.9.0(typescript@5.9.3) + stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)): dependencies: - stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)) - stylelint-config-standard: 40.0.0(stylelint@17.9.0(typescript@5.9.3)) + stylelint: 17.9.1(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.9.1(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.10 + postcss: 8.5.13 - stylelint-config-standard@40.0.0(stylelint@17.9.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.9.1(typescript@5.9.3)): dependencies: - stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) + stylelint: 17.9.1(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) - stylelint-order@6.0.4(stylelint@17.9.0(typescript@5.9.3)): + stylelint-order@6.0.4(stylelint@17.9.1(typescript@5.9.3)): dependencies: - postcss: 8.5.10 - postcss-sorting: 8.0.2(postcss@8.5.10) - stylelint: 17.9.0(typescript@5.9.3) + postcss: 8.5.13 + postcss-sorting: 8.0.2(postcss@8.5.13) + stylelint: 17.9.1(typescript@5.9.3) - stylelint-scss@7.0.0(stylelint@17.9.0(typescript@5.9.3)): + stylelint-scss@7.0.0(stylelint@17.9.1(typescript@5.9.3)): dependencies: css-tree: 3.2.1 is-plain-object: 5.0.0 @@ -13333,13 +13321,13 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - stylelint: 17.9.0(typescript@5.9.3) + stylelint: 17.9.1(typescript@5.9.3) - stylelint-use-logical@2.1.3(stylelint@17.9.0(typescript@5.9.3)): + stylelint-use-logical@2.1.3(stylelint@17.9.1(typescript@5.9.3)): dependencies: - stylelint: 17.9.0(typescript@5.9.3) + stylelint: 17.9.1(typescript@5.9.3) - stylelint@17.9.0(typescript@5.9.3): + stylelint@17.9.1(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -13368,8 +13356,8 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.10 - postcss-safe-parser: 7.0.1(postcss@8.5.10) + postcss: 8.5.13 + postcss-safe-parser: 7.0.1(postcss@8.5.13) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 string-width: 8.2.0 @@ -13845,7 +13833,7 @@ snapshots: esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.10 + postcss: 8.5.13 rollup: 4.60.2 tinyglobby: 0.2.15 optionalDependencies: From d9a5958bb872f03af378b0acad5774f039ec5440 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 3 May 2026 08:29:22 +0000 Subject: [PATCH 021/313] feat: always enable bot users Removes the `service.enablebotusers` config flag, the matching `bot_users_enabled` field on /info, and the now-unused `ErrBotUsersDisabled` error. Bot user routes and the frontend settings tab are now always available. https://claude.ai/code/session_01VhAR6xnoCdG1fpX52bzaCC --- config-raw.json | 5 ----- frontend/src/stores/config.ts | 2 -- frontend/src/views/user/Settings.vue | 2 -- pkg/config/config.go | 2 -- pkg/routes/api/v1/info.go | 2 -- pkg/routes/routes.go | 20 +++++++++----------- pkg/user/error.go | 25 ------------------------- pkg/user/error_test.go | 7 ------- 8 files changed, 9 insertions(+), 56 deletions(-) diff --git a/config-raw.json b/config-raw.json index c49239e6b..dd395b768 100644 --- a/config-raw.json +++ b/config-raw.json @@ -113,11 +113,6 @@ "default_value": "true", "comment": "If true, will allow users to request the complete deletion of their account. When using external authentication methods\nit may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands\nfor user deletion." }, - { - "key": "enablebotusers", - "default_value": "true", - "comment": "If enabled (default), users can create bot users that interact with Vikunja via the API only. Set to false to disable the feature entirely." - }, { "key": "maxavatarsize", "default_value": "1024", diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts index 7784e0507..6ca087ff4 100644 --- a/frontend/src/stores/config.ts +++ b/frontend/src/stores/config.ts @@ -44,7 +44,6 @@ export interface ConfigState { }, }, publicTeamsEnabled: boolean, - botUsersEnabled: boolean, enabledProFeatures: string[], } @@ -85,7 +84,6 @@ export const useConfigStore = defineStore('config', () => { }, }, publicTeamsEnabled: false, - botUsersEnabled: false, enabledProFeatures: [], }) diff --git a/frontend/src/views/user/Settings.vue b/frontend/src/views/user/Settings.vue index 9ac8688d0..aa1b92350 100644 --- a/frontend/src/views/user/Settings.vue +++ b/frontend/src/views/user/Settings.vue @@ -26,7 +26,6 @@ const migratorsEnabled = computed(() => configStore.migratorsEnabled) const isLocalUser = computed(() => authStore.info?.isLocalUser) const userDeletionEnabled = computed(() => configStore.userDeletionEnabled) const webhooksEnabled = computed(() => configStore.webhooksEnabled) -const botUsersEnabled = computed(() => configStore.botUsersEnabled) const navigationItems = computed(() => { const items = [ @@ -84,7 +83,6 @@ const navigationItems = computed(() => { { title: t('user.settings.bots.title'), routeName: 'user.settings.bots', - condition: botUsersEnabled.value, }, { title: t('user.deletion.title'), diff --git a/pkg/config/config.go b/pkg/config/config.go index 099c72e9c..1941f7f0b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -64,7 +64,6 @@ const ( ServiceTestingtoken Key = `service.testingtoken` ServiceEnableEmailReminders Key = `service.enableemailreminders` ServiceEnableUserDeletion Key = `service.enableuserdeletion` - ServiceEnableBotUsers Key = `service.enablebotusers` ServiceMaxAvatarSize Key = `service.maxavatarsize` ServiceAllowIconChanges Key = `service.allowiconchanges` ServiceCustomLogoURL Key = `service.customlogourl` @@ -361,7 +360,6 @@ func InitDefaultConfig() { ServiceEnableTotp.setDefault(true) ServiceEnableEmailReminders.setDefault(true) ServiceEnableUserDeletion.setDefault(true) - ServiceEnableBotUsers.setDefault(true) ServiceMaxAvatarSize.setDefault(1024) ServiceDemoMode.setDefault(false) ServiceAllowIconChanges.setDefault(true) diff --git a/pkg/routes/api/v1/info.go b/pkg/routes/api/v1/info.go index 6e7c9a6ba..0f8ded367 100644 --- a/pkg/routes/api/v1/info.go +++ b/pkg/routes/api/v1/info.go @@ -55,7 +55,6 @@ type vikunjaInfos struct { DemoModeEnabled bool `json:"demo_mode_enabled"` WebhooksEnabled bool `json:"webhooks_enabled"` PublicTeamsEnabled bool `json:"public_teams_enabled"` - BotUsersEnabled bool `json:"bot_users_enabled"` EnabledProFeatures []license.Feature `json:"enabled_pro_features"` } @@ -108,7 +107,6 @@ func Info(c *echo.Context) error { DemoModeEnabled: config.ServiceDemoMode.GetBool(), WebhooksEnabled: config.WebhooksEnabled.GetBool(), PublicTeamsEnabled: config.ServiceEnablePublicTeams.GetBool(), - BotUsersEnabled: config.ServiceEnableBotUsers.GetBool(), EnabledProFeatures: license.EnabledProFeatures(), AvailableMigrators: []string{ (&vikunja_file.FileMigrator{}).Name(), diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index 36e8b8e3e..e37927e5f 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -482,18 +482,16 @@ func registerAPIRoutes(a *echo.Group) { } // Bot users - if config.ServiceEnableBotUsers.GetBool() { - botHandler := &handler.WebHandler{ - EmptyStruct: func() handler.CObject { - return &models.BotUser{} - }, - } - u.PUT("/bots", botHandler.CreateWeb) - u.GET("/bots", botHandler.ReadAllWeb) - u.GET("/bots/:bot", botHandler.ReadOneWeb) - u.POST("/bots/:bot", botHandler.UpdateWeb) - u.DELETE("/bots/:bot", botHandler.DeleteWeb) + botHandler := &handler.WebHandler{ + EmptyStruct: func() handler.CObject { + return &models.BotUser{} + }, } + u.PUT("/bots", botHandler.CreateWeb) + u.GET("/bots", botHandler.ReadAllWeb) + u.GET("/bots/:bot", botHandler.ReadOneWeb) + u.POST("/bots/:bot", botHandler.UpdateWeb) + u.DELETE("/bots/:bot", botHandler.DeleteWeb) projectHandler := &handler.WebHandler{ EmptyStruct: func() handler.CObject { diff --git a/pkg/user/error.go b/pkg/user/error.go index e9007c918..eb9160ac6 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -820,31 +820,6 @@ func (err *ErrAccountIsBot) HTTPError() web.HTTPError { } } -// ErrBotUsersDisabled represents an error where the bot users feature is disabled. -type ErrBotUsersDisabled struct{} - -// IsErrBotUsersDisabled checks if an error is a ErrBotUsersDisabled. -func IsErrBotUsersDisabled(err error) bool { - _, ok := err.(*ErrBotUsersDisabled) - return ok -} - -func (err *ErrBotUsersDisabled) Error() string { - return "Bot users feature is disabled" -} - -// ErrCodeBotUsersDisabled holds the unique world-error code of this error -const ErrCodeBotUsersDisabled = 1032 - -// HTTPError holds the http error description -func (err *ErrBotUsersDisabled) HTTPError() web.HTTPError { - return web.HTTPError{ - HTTPCode: http.StatusForbidden, - Code: ErrCodeBotUsersDisabled, - Message: "Bot users are disabled on this instance.", - } -} - // ErrBotNotOwned represents an error where a user tried to operate on a bot they do not own. type ErrBotNotOwned struct { UserID int64 diff --git a/pkg/user/error_test.go b/pkg/user/error_test.go index de458f74f..f30b292fc 100644 --- a/pkg/user/error_test.go +++ b/pkg/user/error_test.go @@ -30,13 +30,6 @@ func TestErrAccountIsBot(t *testing.T) { assert.Equal(t, 1031, err.HTTPError().Code) } -func TestErrBotUsersDisabled(t *testing.T) { - err := &ErrBotUsersDisabled{} - assert.True(t, IsErrBotUsersDisabled(err)) - assert.Equal(t, http.StatusForbidden, err.HTTPError().HTTPCode) - assert.Equal(t, 1032, err.HTTPError().Code) -} - func TestErrBotNotOwned(t *testing.T) { err := &ErrBotNotOwned{UserID: 7} assert.True(t, IsErrBotNotOwned(err)) From 55e96018f3c15406a7878ebe4cf48bc8eca4c36b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 10:31:37 +0000 Subject: [PATCH 022/313] chore(deps): update dev-dependencies --- frontend/package.json | 4 +- frontend/pnpm-lock.yaml | 92 ++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 2ed07c490..781aed491 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -141,7 +141,7 @@ "rollup": "4.60.2", "rollup-plugin-visualizer": "6.0.11", "sass-embedded": "1.99.0", - "stylelint": "17.9.1", + "stylelint": "17.10.0", "stylelint-config-property-sort-order-smacss": "10.0.0", "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", @@ -154,7 +154,7 @@ "vite-plugin-vue-devtools": "8.1.1", "vite-svg-loader": "5.1.1", "vitest": "4.1.5", - "vue-tsc": "3.2.7", + "vue-tsc": "3.2.8", "wait-on": "9.0.5", "workbox-cli": "7.4.0", "ws": "8.20.0" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 2da3fe358..615a959af 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -281,20 +281,20 @@ importers: specifier: 1.99.0 version: 1.99.0 stylelint: - specifier: 17.9.1 - version: 17.9.1(typescript@5.9.3) + specifier: 17.10.0 + version: 17.10.0(typescript@5.9.3) stylelint-config-property-sort-order-smacss: specifier: 10.0.0 - version: 10.0.0(stylelint@17.9.1(typescript@5.9.3)) + version: 10.0.0(stylelint@17.10.0(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: 1.6.1 - version: 1.6.1(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 - version: 2.1.3(stylelint@17.9.1(typescript@5.9.3)) + version: 2.1.3(stylelint@17.10.0(typescript@5.9.3)) tailwindcss: specifier: 4.2.4 version: 4.2.4 @@ -320,8 +320,8 @@ importers: specifier: 4.1.5 version: 4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: - specifier: 3.2.7 - version: 3.2.7(typescript@5.9.3) + specifier: 3.2.8 + version: 3.2.8(typescript@5.9.3) wait-on: specifier: 9.0.5 version: 9.0.5 @@ -3122,8 +3122,8 @@ packages: typescript: optional: true - '@vue/language-core@3.2.7': - resolution: {integrity: sha512-Gn4q/tRxbpVGLEuARQ43p3YELlNAFgRUVCgW9U5Cr+5q4vfD2bWDWpl3ABbJMXUt5xlE1dF8dkigg2aUq7JYYw==} + '@vue/language-core@3.2.8': + resolution: {integrity: sha512-9OiSPQFiAAWNVnXb0d2dcTmcKnFQamhuNES6ayyISrb/mwPWVgoGdAqSfCWqKhQpa3D5gDTcYD+w7ObiheZ81g==} '@vue/reactivity@3.5.27': resolution: {integrity: sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==} @@ -6243,8 +6243,8 @@ packages: peerDependencies: stylelint: '>= 11 < 18' - stylelint@17.9.1: - resolution: {integrity: sha512-THTmnAPJTrg/JhkTWZlSyrO+HUYMx6ELthIHeMyD2WOKqXIJUFQv2Yxn91bvUrZdbBJaW2dUuQdPST2wcQ6C3g==} + stylelint@17.10.0: + resolution: {integrity: sha512-cI7I6HHEYOHHVNVci+s92WlA3QfmNhjwFdgCgYV3TLEysilOjk+B3EFxMED1xY9GYB0Kre3OD+mSLj19VLTIvA==} engines: {node: '>=20.19.0'} hasBin: true @@ -6782,8 +6782,8 @@ packages: peerDependencies: vue: ^3.5.0 - vue-tsc@3.2.7: - resolution: {integrity: sha512-zc1tL3HoQni1zGTGrwBVRQb7rGP5SWdu/m4rGB6JcnAC5MT5LFZIxF7Y+EJEnt4hGF23d60rXH7gRjHGb5KQQQ==} + vue-tsc@3.2.8: + resolution: {integrity: sha512-27vTLJ6Q2370obOd0PFYoYoKnmXJ521uUIedrs3Zhhhg/8YG10VOCMmwt+JQslatpAMTDbnWiitLnoD5VlIvog==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -9920,7 +9920,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vue/language-core@3.2.7': + '@vue/language-core@3.2.8': dependencies: '@volar/language-core': 2.4.28 '@vue/compiler-dom': 3.5.27 @@ -13260,58 +13260,58 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 - stylelint: 17.9.1(typescript@5.9.3) + stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.10.0(typescript@5.9.3)): dependencies: css-property-sort-order-smacss: 2.2.0 - stylelint: 17.9.1(typescript@5.9.3) - stylelint-order: 6.0.4(stylelint@17.9.1(typescript@5.9.3)) + stylelint: 17.10.0(typescript@5.9.3) + stylelint-order: 6.0.4(stylelint@17.10.0(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)): dependencies: postcss-scss: 4.0.9(postcss@8.5.13) - stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) - stylelint-scss: 7.0.0(stylelint@17.9.1(typescript@5.9.3)) + stylelint: 17.10.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) + stylelint-scss: 7.0.0(stylelint@17.10.0(typescript@5.9.3)) optionalDependencies: postcss: 8.5.13 - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 semver: 7.7.3 - stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.9.1(typescript@5.9.3)) - stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) + stylelint: 17.10.0(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) - stylelint-config-recommended@18.0.0(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.10.0(typescript@5.9.3)): dependencies: - stylelint: 17.9.1(typescript@5.9.3) + stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)): dependencies: - stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.13)(stylelint@17.9.1(typescript@5.9.3)) - stylelint-config-standard: 40.0.0(stylelint@17.9.1(typescript@5.9.3)) + stylelint: 17.10.0(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.10.0(typescript@5.9.3)) optionalDependencies: postcss: 8.5.13 - stylelint-config-standard@40.0.0(stylelint@17.9.1(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.10.0(typescript@5.9.3)): dependencies: - stylelint: 17.9.1(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.9.1(typescript@5.9.3)) + stylelint: 17.10.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) - stylelint-order@6.0.4(stylelint@17.9.1(typescript@5.9.3)): + stylelint-order@6.0.4(stylelint@17.10.0(typescript@5.9.3)): dependencies: postcss: 8.5.13 postcss-sorting: 8.0.2(postcss@8.5.13) - stylelint: 17.9.1(typescript@5.9.3) + stylelint: 17.10.0(typescript@5.9.3) - stylelint-scss@7.0.0(stylelint@17.9.1(typescript@5.9.3)): + stylelint-scss@7.0.0(stylelint@17.10.0(typescript@5.9.3)): dependencies: css-tree: 3.2.1 is-plain-object: 5.0.0 @@ -13321,13 +13321,13 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - stylelint: 17.9.1(typescript@5.9.3) + stylelint: 17.10.0(typescript@5.9.3) - stylelint-use-logical@2.1.3(stylelint@17.9.1(typescript@5.9.3)): + stylelint-use-logical@2.1.3(stylelint@17.10.0(typescript@5.9.3)): dependencies: - stylelint: 17.9.1(typescript@5.9.3) + stylelint: 17.10.0(typescript@5.9.3) - stylelint@17.9.1(typescript@5.9.3): + stylelint@17.10.0(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -13923,10 +13923,10 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.27(typescript@5.9.3) - vue-tsc@3.2.7(typescript@5.9.3): + vue-tsc@3.2.8(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.28 - '@vue/language-core': 3.2.7 + '@vue/language-core': 3.2.8 typescript: 5.9.3 vue@3.5.27(typescript@5.9.3): From 6a604dd949409da59bf94ea2b099ce0532c95cdf Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Mon, 4 May 2026 11:19:21 +0000 Subject: [PATCH 023/313] [skip ci] Updated swagger docs --- pkg/swagger/docs.go | 3 --- pkg/swagger/swagger.json | 3 --- pkg/swagger/swagger.yaml | 2 -- 3 files changed, 8 deletions(-) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index 8af387674..a464c493a 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -11201,9 +11201,6 @@ const docTemplate = `{ "type": "string" } }, - "bot_users_enabled": { - "type": "boolean" - }, "caldav_enabled": { "type": "boolean" }, diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index f58832190..9d2735d0d 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -11193,9 +11193,6 @@ "type": "string" } }, - "bot_users_enabled": { - "type": "boolean" - }, "caldav_enabled": { "type": "boolean" }, diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index f186de3f1..c05086307 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -1771,8 +1771,6 @@ definitions: items: type: string type: array - bot_users_enabled: - type: boolean caldav_enabled: type: boolean demo_mode_enabled: From 459dbe71ca857304a5ffba7d94defd0beb279fb4 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 4 May 2026 15:33:59 +0200 Subject: [PATCH 024/313] Improve modal responsive sizing with inline-size constraints (#2716) --- frontend/src/components/misc/Modal.vue | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/src/components/misc/Modal.vue b/frontend/src/components/misc/Modal.vue index 356774f9b..f33dd5aac 100644 --- a/frontend/src/components/misc/Modal.vue +++ b/frontend/src/components/misc/Modal.vue @@ -256,6 +256,20 @@ $modal-width: 1024px; } } +// Default width for centered modals. Scoped with :not(.is-wide) so the +// `wide` prop can still expand the modal (the .is-wide rule below would +// otherwise be outranked by .default .modal-content's specificity). +.default .modal-content:not(.is-wide), +.hint-modal .modal-content:not(.is-wide) { + inline-size: calc(100% - 2rem); + max-inline-size: 640px; + + @media screen and (max-width: $tablet) { + inline-size: 100%; + max-inline-size: none; + } +} + // scrolling-content // used e.g. for .scrolling .modal-content { From 65a6fc7b4bf89de898dbca08f3487c12eb83c9fd Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Tue, 5 May 2026 01:57:03 +0000 Subject: [PATCH 025/313] chore(i18n): update translations via Crowdin --- frontend/src/i18n/lang/de-DE.json | 97 +++++++++++++++++++++++++++- frontend/src/i18n/lang/de-swiss.json | 97 +++++++++++++++++++++++++++- 2 files changed, 188 insertions(+), 6 deletions(-) diff --git a/frontend/src/i18n/lang/de-DE.json b/frontend/src/i18n/lang/de-DE.json index 02791edd9..4d88eaa68 100644 --- a/frontend/src/i18n/lang/de-DE.json +++ b/frontend/src/i18n/lang/de-DE.json @@ -107,6 +107,19 @@ "registrationFailed": "Bei der Registrierung ist ein Fehler aufgetreten. Bitte prüfe deine Eingabe und versuche es erneut." }, "settings": { + "bots": { + "title": "Bot-Accounts", + "description": "Bot-Accounts gehören zu dir und können nur die API nutzen. Sie können zu Projekten, zugewiesenen Aufgaben hinzugefügt und mit API-Token authentifiziert werden und sich nicht selbst anmelden.", + "namePlaceholder": "Mein Assistent", + "create": "Bot Erstellen", + "enable": "Aktivieren", + "badge": "Bot", + "delete": { + "header": "Diesen Bot-Account löschen", + "text1": "Bist Du sicher, dass Du den Bot-Account \"{username}\" löschen möchtest?", + "text2": "Dies ist unwiderruflich. Alle API-Token dieses Bots werden widerrufen." + } + }, "title": "Einstellungen", "newPasswordTitle": "Aktualisiere dein Passwort", "newPassword": "Neues Passwort", @@ -132,6 +145,11 @@ "weekStart": "Woche beginnt am", "weekStartSunday": "Sonntag", "weekStartMonday": "Montag", + "weekStartTuesday": "Dienstag", + "weekStartWednesday": "Mittwoch", + "weekStartThursday": "Donnerstag", + "weekStartFriday": "Freitag", + "weekStartSaturday": "Samstag", "language": "Sprache", "defaultProject": "Standardprojekt", "defaultView": "Standardansicht", @@ -495,7 +513,8 @@ "bucketTitleSavedSuccess": "Der Spaltenname wurde erfolgreich gespeichert.", "bucketLimitSavedSuccess": "Das Spaltenlimit wurde erfolgreich gespeichert.", "collapse": "Spalte einklappen", - "bucketLimitReached": "Du hast das Limit dieses Buckets erreicht. Entferne Aufgaben oder erhöhe das Limit, um neue Aufgaben hinzuzufügen." + "bucketLimitReached": "Du hast das Limit dieses Buckets erreicht. Entferne Aufgaben oder erhöhe das Limit, um neue Aufgaben hinzuzufügen.", + "bucketOptions": "Bucketoptionen" }, "pseudo": { "favorites": { @@ -718,7 +737,9 @@ "upcoming": "Anstehend", "settings": "Einstellungen", "imprint": "Impressum", - "privacy": "Datenschutzerklärung" + "privacy": "Datenschutzerklärung", + "closeSidebar": "Seitenleiste schließen", + "home": "Vikunja Startseite" }, "misc": { "loading": "Wird geladen…", @@ -750,9 +771,15 @@ "createdBy": "Erstellt von {0}", "actions": "Aktionen", "cannotBeUndone": "Dies kann nicht rückgängig gemacht werden!", - "avatarOfUser": "{user}'s Profilbild" + "avatarOfUser": "{user}'s Profilbild", + "closeBanner": "Banner schließen", + "closeDialog": "Dialog schließen", + "closeQuickActions": "Schnellaktionen schließen", + "skipToContent": "Überspringen und zum Hauptinhalt gehen", + "sortBy": "Sortieren nach" }, "input": { + "projectColor": "Projektfarbe", "resetColor": "Farbe zurücksetzen", "datepicker": { "today": "Heute", @@ -935,6 +962,9 @@ "belongsToProject": "Diese Aufgabe gehört zum Projekt „{project}“", "back": "Zurück zum Projekt", "due": "Fällig {at}", + "closeTaskDetail": "Aufgabendetails schließen", + "title": "Aufgabendetails", + "markAsDone": "'{task}' als erledigt markieren", "scrollToBottom": "Nach unten scrollen", "organization": "Organisation", "management": "Verwaltung", @@ -1429,5 +1459,66 @@ "weeks": "Woche|Wochen", "years": "Jahr|Jahre" } + }, + "admin": { + "title": "Administration", + "labels": { + "users": "Accounts", + "tasks": "Aufgaben" + }, + "overview": { + "shares": "Freigaben", + "linkSharesShort": "link", + "teamSharesShort": "Team", + "userSharesShort": "Benutzer:in", + "version": "Version", + "license": "Lizenz", + "licenseValidUntil": "Gültig bis", + "licenseExpiresIn": "in {days} Tagen", + "licenseLastVerified": "Zuletzt geprüft", + "licenseNever": "nie", + "licenseLastCheckFailed": "letzte Prüfung fehlgeschlagen", + "licenseFeatures": "Features", + "licenseInstance": "Instanz-ID", + "licenseManage": "Verwalten" + }, + "searchUsersPlaceholder": "Suche nach Anmeldename oder E-Mail…", + "users": { + "status": "Status", + "details": "Details", + "detailsTitle": "Account: {username}", + "issuer": "Aussteller", + "issuerLocal": "Lokal", + "issuerUrl": "Aussteller-URL", + "subject": "Betreff", + "statusActive": "Aktiv", + "statusEmailConfirmation": "E-Mail-Bestätigung erforderlich", + "statusDisabled": "Deaktiviert", + "statusLocked": "Account gesperrt", + "isAdminLabel": "Administrator", + "addUser": "Account hinzufügen", + "createTitle": "Account erstellen", + "nameLabel": "Name", + "skipEmailConfirm": "E-Mail-Bestätigung überspringen", + "createSubmit": "Account erstellen", + "saveButton": "Änderungen speichern", + "createdSuccess": "Account {username} erstellt.", + "updatedSuccess": "Account {username} aktualisiert.", + "deletedSuccess": "Account {username} gelöscht.", + "deleteScheduledSuccess": "{username} erhält eine Bestätigungs-E-Mail, um die Löschung zu planen.", + "confirmDeleteTitle": "Account löschen?", + "confirmDeleteIntro": "Wie soll der Account {username} gelöscht werden?", + "deleteModeScheduled": "Löschung planen", + "deleteModeScheduledHelp": "\"Löschung planen\" sendet eine Bestätigungs-E-Mail, analog zu einer selbst ausgelösten Kontolöschung.", + "deleteModeNow": "Jetzt löschen", + "deleteModeNowHelp": "Sofort-Löschen entfernt den Account und seine Daten umgehend. Dies kann nicht rückgängig gemacht werden." + }, + "projects": { + "ownerLabel": "Eigentümer:in", + "reassignOwner": "Eigentümer:in neu zuweisen", + "reassignTitle": "{title} erneut zuweisen", + "reassignedSuccess": "Projekteigentümer:in neu zugewiesen.", + "newOwnerLabel": "Neu:e Eigentümer:in" + } } } \ No newline at end of file diff --git a/frontend/src/i18n/lang/de-swiss.json b/frontend/src/i18n/lang/de-swiss.json index 13c155460..c20af1643 100644 --- a/frontend/src/i18n/lang/de-swiss.json +++ b/frontend/src/i18n/lang/de-swiss.json @@ -107,6 +107,19 @@ "registrationFailed": "Bei der Registrierung ist ein Fehler aufgetreten. Bitte prüfe deine Eingabe und versuche es erneut." }, "settings": { + "bots": { + "title": "Bot-Accounts", + "description": "Bot-Accounts gehören zu dir und können nur die API nutzen. Sie können zu Projekten, zugewiesenen Aufgaben hinzugefügt und mit API-Token authentifiziert werden und sich nicht selbst anmelden.", + "namePlaceholder": "Mein Assistent", + "create": "Bot Erstellen", + "enable": "Aktivieren", + "badge": "Bot", + "delete": { + "header": "Diesen Bot-Account löschen", + "text1": "Bist Du sicher, dass Du den Bot-Account \"{username}\" löschen möchtest?", + "text2": "Dies ist unwiderruflich. Alle API-Token dieses Bots werden widerrufen." + } + }, "title": "Iihstellige", "newPasswordTitle": "Diis Passwort aktualisierä", "newPassword": "Neues Passwort", @@ -132,6 +145,11 @@ "weekStart": "D'Wuche fangt ah am", "weekStartSunday": "Sunntig", "weekStartMonday": "Määntig", + "weekStartTuesday": "Dienstag", + "weekStartWednesday": "Mittwoch", + "weekStartThursday": "Donnerstag", + "weekStartFriday": "Freitag", + "weekStartSaturday": "Samstag", "language": "Sproch", "defaultProject": "Standardprojekt", "defaultView": "Standardansicht", @@ -495,7 +513,8 @@ "bucketTitleSavedSuccess": "Der Spaltenname wurde erfolgreich gespeichert.", "bucketLimitSavedSuccess": "Das Spaltenlimit wurde erfolgreich gespeichert.", "collapse": "Spalte einklappen", - "bucketLimitReached": "Du hast das Limit dieses Buckets erreicht. Entferne Aufgaben oder erhöhe das Limit, um neue Aufgaben hinzuzufügen." + "bucketLimitReached": "Du hast das Limit dieses Buckets erreicht. Entferne Aufgaben oder erhöhe das Limit, um neue Aufgaben hinzuzufügen.", + "bucketOptions": "Bucketoptionen" }, "pseudo": { "favorites": { @@ -718,7 +737,9 @@ "upcoming": "Ahstehänd", "settings": "Iihstellige", "imprint": "Immpressum", - "privacy": "Dateschutzerchlärig" + "privacy": "Dateschutzerchlärig", + "closeSidebar": "Seitenleiste schließen", + "home": "Vikunja Startseite" }, "misc": { "loading": "Ladä…", @@ -750,9 +771,15 @@ "createdBy": "Erstellt von {0}", "actions": "Aktionen", "cannotBeUndone": "Dies kann nicht rückgängig gemacht werden!", - "avatarOfUser": "{user}'s Profilbild" + "avatarOfUser": "{user}'s Profilbild", + "closeBanner": "Banner schließen", + "closeDialog": "Dialog schließen", + "closeQuickActions": "Schnellaktionen schließen", + "skipToContent": "Überspringen und zum Hauptinhalt gehen", + "sortBy": "Sortieren nach" }, "input": { + "projectColor": "Projektfarbe", "resetColor": "Farb zruggsetze", "datepicker": { "today": "Hütt", @@ -935,6 +962,9 @@ "belongsToProject": "Diese Aufgabe gehört zum Projekt „{project}“", "back": "Zurück zum Projekt", "due": "Fällig bis {at}", + "closeTaskDetail": "Aufgabendetails schließen", + "title": "Aufgabendetails", + "markAsDone": "'{task}' als erledigt markieren", "scrollToBottom": "Nach unten scrollen", "organization": "Organisation", "management": "Verwaltung", @@ -1429,5 +1459,66 @@ "weeks": "Woche|Wochen", "years": "Jahr|Jahre" } + }, + "admin": { + "title": "Administration", + "labels": { + "users": "Accounts", + "tasks": "Aufgaben" + }, + "overview": { + "shares": "Freigaben", + "linkSharesShort": "link", + "teamSharesShort": "Team", + "userSharesShort": "Benutzer:in", + "version": "Version", + "license": "Lizenz", + "licenseValidUntil": "Gültig bis", + "licenseExpiresIn": "in {days} Tagen", + "licenseLastVerified": "Zuletzt geprüft", + "licenseNever": "nie", + "licenseLastCheckFailed": "letzte Prüfung fehlgeschlagen", + "licenseFeatures": "Features", + "licenseInstance": "Instanz-ID", + "licenseManage": "Verwalten" + }, + "searchUsersPlaceholder": "Suche nach Anmeldename oder E-Mail…", + "users": { + "status": "Status", + "details": "Details", + "detailsTitle": "Account: {username}", + "issuer": "Aussteller", + "issuerLocal": "Lokal", + "issuerUrl": "Aussteller-URL", + "subject": "Betreff", + "statusActive": "Aktiv", + "statusEmailConfirmation": "E-Mail-Bestätigung erforderlich", + "statusDisabled": "Deaktiviert", + "statusLocked": "Account gesperrt", + "isAdminLabel": "Administrator", + "addUser": "Account hinzufügen", + "createTitle": "Account erstellen", + "nameLabel": "Name", + "skipEmailConfirm": "E-Mail-Bestätigung überspringen", + "createSubmit": "Account erstellen", + "saveButton": "Änderungen speichern", + "createdSuccess": "Account {username} erstellt.", + "updatedSuccess": "Account {username} aktualisiert.", + "deletedSuccess": "Account {username} gelöscht.", + "deleteScheduledSuccess": "{username} erhält eine Bestätigungs-E-Mail, um die Löschung zu planen.", + "confirmDeleteTitle": "Account löschen?", + "confirmDeleteIntro": "Wie soll der Account {username} gelöscht werden?", + "deleteModeScheduled": "Löschung planen", + "deleteModeScheduledHelp": "\"Löschung planen\" sendet eine Bestätigungs-E-Mail, analog zu einer selbst ausgelösten Kontolöschung.", + "deleteModeNow": "Jetzt löschen", + "deleteModeNowHelp": "Sofort-Löschen entfernt den Account und seine Daten umgehend. Dies kann nicht rückgängig gemacht werden." + }, + "projects": { + "ownerLabel": "Eigentümer:in", + "reassignOwner": "Eigentümer:in neu zuweisen", + "reassignTitle": "{title} erneut zuweisen", + "reassignedSuccess": "Projekteigentümer:in neu zugewiesen.", + "newOwnerLabel": "Neu:e Eigentümer:in" + } } } \ No newline at end of file From 7ed0e3ecd6206413da3f983e2b3aba11455a1098 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 22:11:26 +0000 Subject: [PATCH 026/313] chore(deps): update dev-dependencies --- frontend/package.json | 10 +- frontend/pnpm-lock.yaml | 1905 ++++++++++++++++++++++----------------- 2 files changed, 1062 insertions(+), 853 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 781aed491..81926f33e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -116,8 +116,8 @@ "@types/node": "24.12.2", "@types/sortablejs": "1.15.9", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.59.1", - "@typescript-eslint/parser": "8.59.1", + "@typescript-eslint/eslint-plugin": "8.59.2", + "@typescript-eslint/parser": "8.59.2", "@vitejs/plugin-vue": "6.0.6", "@vue/eslint-config-typescript": "14.7.0", "@vue/test-utils": "2.4.10", @@ -134,11 +134,11 @@ "happy-dom": "20.9.0", "histoire": "1.0.0-beta.1", "otplib": "12.0.1", - "postcss": "8.5.13", + "postcss": "8.5.14", "postcss-easing-gradients": "3.0.1", "postcss-html": "1.8.1", "postcss-preset-env": "11.2.1", - "rollup": "4.60.2", + "rollup": "4.60.3", "rollup-plugin-visualizer": "6.0.11", "sass-embedded": "1.99.0", "stylelint": "17.10.0", @@ -156,7 +156,7 @@ "vitest": "4.1.5", "vue-tsc": "3.2.8", "wait-on": "9.0.5", - "workbox-cli": "7.4.0", + "workbox-cli": "7.4.1", "ws": "8.20.0" }, "pnpm": { diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 615a959af..4ea725738 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: overrides: minimatch: ^10.2.3 - rollup: 4.60.2 + rollup: 4.60.3 basic-ftp: '>=5.2.2' serialize-javascript: ^7.0.5 flatted: ^3.4.1 @@ -32,7 +32,7 @@ importers: version: 3.1.3(@fortawesome/fontawesome-svg-core@7.1.0)(vue@3.5.27(typescript@5.9.3)) '@intlify/unplugin-vue-i18n': specifier: 11.0.3 - version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.2)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) + version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.3)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) '@kyvg/vue3-notification': specifier: 3.4.2 version: 3.4.2(vue@3.5.27(typescript@5.9.3)) @@ -206,17 +206,17 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.59.1 - version: 8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.2 + version: 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.59.1 - version: 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.2 + version: 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.6 version: 6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': specifier: 2.4.10 version: 2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) @@ -228,7 +228,7 @@ importers: version: 14.3.0(vue@3.5.27(typescript@5.9.3)) autoprefixer: specifier: 10.5.0 - version: 10.5.0(postcss@8.5.13) + version: 10.5.0(postcss@8.5.14) browserslist: specifier: 4.28.2 version: 4.28.2 @@ -249,7 +249,7 @@ importers: version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: specifier: 10.9.0 - version: 10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + version: 10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: specifier: 20.9.0 version: 20.9.0 @@ -260,8 +260,8 @@ importers: specifier: 12.0.1 version: 12.0.1 postcss: - specifier: 8.5.13 - version: 8.5.13 + specifier: 8.5.14 + version: 8.5.14 postcss-easing-gradients: specifier: 3.0.1 version: 3.0.1 @@ -270,13 +270,13 @@ importers: version: 1.8.1 postcss-preset-env: specifier: 11.2.1 - version: 11.2.1(postcss@8.5.13) + version: 11.2.1(postcss@8.5.14) rollup: - specifier: 4.60.2 - version: 4.60.2 + specifier: 4.60.3 + version: 4.60.3 rollup-plugin-visualizer: specifier: 6.0.11 - version: 6.0.11(rollup@4.60.2) + version: 6.0.11(rollup@4.60.3) sass-embedded: specifier: 1.99.0 version: 1.99.0 @@ -291,7 +291,7 @@ importers: version: 1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 version: 2.1.3(stylelint@17.10.0(typescript@5.9.3)) @@ -309,7 +309,7 @@ importers: version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: specifier: 1.2.0 - version: 1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0) + version: 1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) vite-plugin-vue-devtools: specifier: 8.1.1 version: 8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) @@ -326,8 +326,8 @@ importers: specifier: 9.0.5 version: 9.0.5 workbox-cli: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.4.1 + version: 7.4.1 ws: specifier: 8.20.0 version: 8.20.0 @@ -2178,177 +2178,177 @@ packages: '@rolldown/pluginutils@1.0.0-rc.13': resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} - '@rollup/plugin-babel@5.3.1': - resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} - engines: {node: '>= 10.0.0'} + '@rollup/plugin-babel@6.1.0': + resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==} + engines: {node: '>=14.0.0'} peerDependencies: '@babel/core': ^7.0.0 '@types/babel__core': ^7.1.9 - rollup: 4.60.2 + rollup: 4.60.3 peerDependenciesMeta: '@types/babel__core': optional: true + rollup: + optional: true - '@rollup/plugin-node-resolve@15.2.3': - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.2 + rollup: 4.60.3 peerDependenciesMeta: rollup: optional: true - '@rollup/plugin-replace@2.4.2': - resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} - peerDependencies: - rollup: 4.60.2 - - '@rollup/plugin-terser@0.4.4': - resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.2 + rollup: 4.60.3 peerDependenciesMeta: rollup: optional: true - '@rollup/pluginutils@3.1.0': - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} + '@rollup/plugin-terser@1.0.0': + resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} + engines: {node: '>=20.0.0'} peerDependencies: - rollup: 4.60.2 + rollup: 4.60.3 + peerDependenciesMeta: + rollup: + optional: true '@rollup/pluginutils@5.1.3': resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.2 + rollup: 4.60.3 peerDependenciesMeta: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.2': - resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} + '@rollup/rollup-android-arm-eabi@4.60.3': + resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.2': - resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} + '@rollup/rollup-android-arm64@4.60.3': + resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.2': - resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} + '@rollup/rollup-darwin-arm64@4.60.3': + resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.2': - resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} + '@rollup/rollup-darwin-x64@4.60.3': + resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.2': - resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} + '@rollup/rollup-freebsd-arm64@4.60.3': + resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.2': - resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} + '@rollup/rollup-freebsd-x64@4.60.3': + resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.2': - resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.60.2': - resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} + '@rollup/rollup-linux-arm-musleabihf@4.60.3': + resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.60.2': - resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} + '@rollup/rollup-linux-arm64-gnu@4.60.3': + resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.60.2': - resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} + '@rollup/rollup-linux-arm64-musl@4.60.3': + resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.60.2': - resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} + '@rollup/rollup-linux-loong64-gnu@4.60.3': + resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-musl@4.60.2': - resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} + '@rollup/rollup-linux-loong64-musl@4.60.3': + resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.60.2': - resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} + '@rollup/rollup-linux-ppc64-gnu@4.60.3': + resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-musl@4.60.2': - resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} + '@rollup/rollup-linux-ppc64-musl@4.60.3': + resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.60.2': - resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} + '@rollup/rollup-linux-riscv64-gnu@4.60.3': + resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.60.2': - resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} + '@rollup/rollup-linux-riscv64-musl@4.60.3': + resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.60.2': - resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} + '@rollup/rollup-linux-s390x-gnu@4.60.3': + resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.60.2': - resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} + '@rollup/rollup-linux-x64-gnu@4.60.3': + resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.60.2': - resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} + '@rollup/rollup-linux-x64-musl@4.60.3': + resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==} cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.60.2': - resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} + '@rollup/rollup-openbsd-x64@4.60.3': + resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.2': - resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} + '@rollup/rollup-openharmony-arm64@4.60.3': + resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.2': - resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} + '@rollup/rollup-win32-arm64-msvc@4.60.3': + resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.2': - resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} + '@rollup/rollup-win32-ia32-msvc@4.60.3': + resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.2': - resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} + '@rollup/rollup-win32-x64-gnu@4.60.3': + resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.2': - resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} + '@rollup/rollup-win32-x64-msvc@4.60.3': + resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==} cpu: [x64] os: [win32] @@ -2485,9 +2485,6 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@surma/rollup-plugin-off-main-thread@2.2.3': - resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} - '@tailwindcss/node@4.2.4': resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} @@ -2766,6 +2763,10 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@trickfilm400/rollup-plugin-off-main-thread@3.0.0-pre1': + resolution: {integrity: sha512-/67zpWDBLV+oYAEL682s1ktXL0HgqX76f6gaVGkGnVZlBbm1zd0v4Bz8MFF2GGhoX9rvfq3KSQHubFHwa6w6/Q==} + engines: {node: '>=12'} + '@tsconfig/node24@24.0.4': resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==} @@ -2778,9 +2779,6 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/estree@0.0.39': - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -2855,11 +2853,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.59.1': - resolution: {integrity: sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==} + '@typescript-eslint/eslint-plugin@8.59.2': + resolution: {integrity: sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.1 + '@typescript-eslint/parser': ^8.59.2 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -2870,8 +2868,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.59.1': - resolution: {integrity: sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==} + '@typescript-eslint/parser@8.59.2': + resolution: {integrity: sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2889,8 +2887,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.1': - resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} + '@typescript-eslint/project-service@8.59.2': + resolution: {integrity: sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2903,8 +2901,8 @@ packages: resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.1': - resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} + '@typescript-eslint/scope-manager@8.59.2': + resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.56.0': @@ -2919,14 +2917,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.0': - resolution: {integrity: sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==} + '@typescript-eslint/tsconfig-utils@8.59.1': + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.1': - resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} + '@typescript-eslint/tsconfig-utils@8.59.2': + resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2938,8 +2936,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.59.1': - resolution: {integrity: sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==} + '@typescript-eslint/type-utils@8.59.2': + resolution: {integrity: sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2953,14 +2951,14 @@ packages: resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.0': - resolution: {integrity: sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.1': resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.2': + resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.0': resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2973,8 +2971,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/typescript-estree@8.59.1': - resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} + '@typescript-eslint/typescript-estree@8.59.2': + resolution: {integrity: sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2993,8 +2991,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.1': - resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} + '@typescript-eslint/utils@8.59.2': + resolution: {integrity: sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3008,8 +3006,8 @@ packages: resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.1': - resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} + '@typescript-eslint/visitor-keys@8.59.2': + resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -3255,12 +3253,12 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} arrify@1.0.1: @@ -3275,6 +3273,10 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -3414,10 +3416,6 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - bulma-css-variables@0.9.33: resolution: {integrity: sha512-D85dXLyLOBBDCuSSOeASc0kN2IknJqo5hzkZ22hxDHobxko/qay0nD+zNl2CJtF8v/7iwvQXqzVSDRnFVRSg9A==} deprecated: bulma-css-variables is deprecated. Project has been shifted to monorepo @bulvar/bulma @@ -3437,8 +3435,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -3685,16 +3683,16 @@ packages: resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} engines: {node: '>=20'} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} dayjs@1.11.19: @@ -3907,8 +3905,8 @@ packages: error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} engines: {node: '>= 0.4'} es-define-property@1.0.1: @@ -3933,8 +3931,8 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} esbuild@0.25.12: @@ -4046,9 +4044,6 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} - estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -4059,6 +4054,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eta@4.6.0: + resolution: {integrity: sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==} + engines: {node: '>=20'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -4182,6 +4181,10 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -4217,8 +4220,8 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} functions-have-names@1.2.3: @@ -4228,6 +4231,10 @@ packages: resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} engines: {node: '>=10'} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -4255,8 +4262,8 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} get-uri@6.0.4: @@ -4358,8 +4365,8 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} has-symbols@1.1.0: @@ -4483,36 +4490,37 @@ packages: resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} engines: {node: '>=8.0.0'} - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} - is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -4521,14 +4529,18 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} - is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -4547,10 +4559,18 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -4573,6 +4593,10 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -4584,8 +4608,8 @@ packages: resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -4611,43 +4635,60 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} is-regexp@1.0.0: resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} engines: {node: '>=0.10.0'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + is-touch-device@1.0.1: resolution: {integrity: sha512-LAYzo9kMT1b2p19L/1ATGt2XcSilnzNlyvq6c0pbPRVisLbAPpLqr53tIJS00kvrTkj0HtR8U7+u8X0yR8lPSw==} - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} is-what@4.1.16: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} @@ -4923,9 +4964,6 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -5134,8 +5172,8 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} obug@2.1.1: @@ -5187,6 +5225,10 @@ packages: otplib@12.0.1: resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -5519,8 +5561,8 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.5.13: - resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} + postcss@8.5.14: + resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -5678,6 +5720,10 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + regenerate-unicode-properties@10.2.0: resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} @@ -5700,8 +5746,8 @@ packages: regex@6.0.1: resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} regexpu-core@6.1.1: @@ -5759,15 +5805,15 @@ packages: hasBin: true peerDependencies: rolldown: 1.x || ^1.0.0-beta - rollup: 4.60.2 + rollup: 4.60.3 peerDependenciesMeta: rolldown: optional: true rollup: optional: true - rollup@4.60.2: - resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} + rollup@4.60.3: + resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -5796,15 +5842,19 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} safer-buffer@2.1.2: @@ -5961,6 +6011,10 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -6054,10 +6108,6 @@ packages: engines: {node: '>= 8'} deprecated: The work that was done in this beta branch won't be included in future versions - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -6093,6 +6143,10 @@ packages: std-env@4.0.0: resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + streamx@2.22.0: resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} @@ -6112,16 +6166,17 @@ packages: resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} engines: {node: '>=20'} - string.prototype.matchall@4.0.11: - resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} engines: {node: '>= 0.4'} - string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} @@ -6440,20 +6495,20 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} typed-query-selector@2.12.0: @@ -6477,8 +6532,9 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} @@ -6861,11 +6917,20 @@ packages: when-exit@2.1.5: resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@1.3.1: @@ -6890,59 +6955,71 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workbox-background-sync@7.4.0: - resolution: {integrity: sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==} + workbox-background-sync@7.4.1: + resolution: {integrity: sha512-HhT7KE8tOWDm02wRNshXUnUPofMlhenF2DBdUnDPOubhizzPeItkYTmAB6td1Z2cjYPa98vzEiPLEuzn5hN66g==} - workbox-broadcast-update@7.4.0: - resolution: {integrity: sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==} + workbox-broadcast-update@7.4.1: + resolution: {integrity: sha512-uAlgslKLvbQY+suirIdnBCSYrcgBhjp81Nj4l1lj/Jmj0MJO2CJERnCJjT0GFVwmReV0N+zs78K6gqd5gr9/+A==} - workbox-build@7.4.0: - resolution: {integrity: sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==} + workbox-build@7.4.1: + resolution: {integrity: sha512-SDhxIvEAde9Gy/5w4Yo1Jh/M49Z0qE3q0oteyE8zGq0DScxFqVBcCtIXFuLtmtxRQZCMbf0prco4VyEu3KBQuw==} engines: {node: '>=20.0.0'} - workbox-cacheable-response@7.4.0: - resolution: {integrity: sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==} + workbox-cacheable-response@7.4.1: + resolution: {integrity: sha512-8xaFoJdDc2OjrlbbL3gEeBO1WKcMwRqwLRupgqahYXu75yXajPLuwrbXMrIGZuWYXrQwk0xDjOxZ/ujCy/oJYw==} - workbox-cli@7.4.0: - resolution: {integrity: sha512-BTc9CbW+aXMyIxBdW2mX+dLYHwTeCdKARX0zpjLvR/mZ2ho/7d9XWckwgFGLQRsJfcxml5WngNqp1PG7+qa9Ug==} + workbox-cli@7.4.1: + resolution: {integrity: sha512-ssOp3t5AQ4i9ZpoClekisv+RT3iSqsR++5GDlarGvn59Agz1io2O3ssJ//W90OIuLL526Uhsdepwk1tQdqKtKw==} engines: {node: '>=20.0.0'} hasBin: true workbox-core@7.4.0: resolution: {integrity: sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==} - workbox-expiration@7.4.0: - resolution: {integrity: sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==} + workbox-core@7.4.1: + resolution: {integrity: sha512-DT+vu46eh/2vRsSHTY4Xmc32Z1rr9PRlQUXr1Dx30ZuXRWwOsvZgGgcwxcasubQLQmbTNYZjv44LkBAQ4tT5tQ==} - workbox-google-analytics@7.4.0: - resolution: {integrity: sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==} + workbox-expiration@7.4.1: + resolution: {integrity: sha512-lRKUF7b+OGbeXkQk1s6MHXOa3d7Xxf7Of31W6c6hCfipfIyrtdWZ89stq21AHZMaoG7VNFoHply4Ox+rU31TWg==} - workbox-navigation-preload@7.4.0: - resolution: {integrity: sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==} + workbox-google-analytics@7.4.1: + resolution: {integrity: sha512-Mks1JwLEt++ZAkF6sS1OpSh9RtAMIsiDgRpK+codiHGIPXeaUOgi4cPc3GFadUl8V5QPeypEk8Oxgl3HlwVzHw==} + + workbox-navigation-preload@7.4.1: + resolution: {integrity: sha512-C4KVsjPcYKJOhr631AxR9XoG2rLF3QiTk5aMv36MXOjtWvm8axwNFAtKUPGsWUwLXXAMgYM1En7fsvndaXeXRQ==} workbox-precaching@7.4.0: resolution: {integrity: sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==} - workbox-range-requests@7.4.0: - resolution: {integrity: sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==} + workbox-precaching@7.4.1: + resolution: {integrity: sha512-cdr/9qByww7yzEp7zg/qI4ukUrrNjQLgN+ONQRpjy/VqGQXwkgHwr00KksGJK8v0VifwDXBb8a4cWNZH71jn3Q==} - workbox-recipes@7.4.0: - resolution: {integrity: sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==} + workbox-range-requests@7.4.1: + resolution: {integrity: sha512-7i2oxAUE82gHdAJBCAQ04JzNOdRPqzuOzGfoUyJpFSmeqBNYGPrAH8GPoPjUQTfp+NycwrD2H68VtuF8qxv0vQ==} + + workbox-recipes@7.4.1: + resolution: {integrity: sha512-gnbVfmV4/TtmQaM4x9AtuXhcdstJsep3XMVeztOrQVPT+R6+6DeBjGTCQ7fFCXm+4GEHUA5VEBTyi5+4gWGeog==} workbox-routing@7.4.0: resolution: {integrity: sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==} + workbox-routing@7.4.1: + resolution: {integrity: sha512-yubJGErZOusuidAenaL5ypfhQOa7urxP/f8E0ws7FPb4039RiWXUWBAyUkmUoOL/BcQGen3h0J8872d51IYxtA==} + workbox-strategies@7.4.0: resolution: {integrity: sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==} - workbox-streams@7.4.0: - resolution: {integrity: sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==} + workbox-strategies@7.4.1: + resolution: {integrity: sha512-GZxpaw9NbmOelj7667uZ2kpk5BFpOGbO4X0qjwh5ls8XQ8C+Lha5LQchTiUzsTFSS+NlUpftYAyOVXvQUrcqOQ==} - workbox-sw@7.4.0: - resolution: {integrity: sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==} + workbox-streams@7.4.1: + resolution: {integrity: sha512-HWWtraKUbJknd9kgqGcpQ3G114HOPYvqs8HaJMDs2ebLNAimDkVDaWfAXE6Ybl+m8U6KsCE6pWyLYuigWmnAXw==} - workbox-window@7.4.0: - resolution: {integrity: sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==} + workbox-sw@7.4.1: + resolution: {integrity: sha512-fez5f2DUlDJWTFYkCWQpY10N8gtztd849NswCbVFk0QlcSM4HT5A8x4g4ii650yem4I8tHY0R7JZahwp3ltIPw==} + + workbox-window@7.4.1: + resolution: {integrity: sha512-notZDH2u8VXaqyuD7xaqIfEFi6SRM4SUSd7ewe9PDsVqADuepxX2ZMY3uvuZGxzY5ZOsGC/vD3A/3smFtJt4/A==} wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} @@ -7885,283 +7962,283 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.13)': + '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.13)': + '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.14)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.13)': + '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-color-function@5.0.3(postcss@8.5.13)': + '@csstools/postcss-color-function@5.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.13)': + '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.13)': + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.13)': + '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.13)': + '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.13)': + '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.13)': + '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.14)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.13)': + '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.14)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.13)': + '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.13)': + '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.13)': + '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.13)': + '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.14)': dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-initial@3.0.0(postcss@8.5.13)': + '@csstools/postcss-initial@3.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.13)': + '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.14)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.13)': + '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.13)': + '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.13)': + '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.13)': + '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.13)': + '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.13)': + '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.14)': dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.13)': + '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.13)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-mixins@1.0.0(postcss@8.5.13)': + '@csstools/postcss-mixins@1.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.13)': + '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.14)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.13)': + '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.13)': + '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.13)': + '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.13)': + '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.13)': + '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-random-function@3.0.2(postcss@8.5.13)': + '@csstools/postcss-random-function@3.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.13)': + '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.14)': dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.13)': + '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.13)': + '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.13)': + '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.13)': + '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.14)': dependencies: '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.13)': + '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.13)': + '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.14)': dependencies: '@csstools/color-helpers': 6.0.2 - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.13)': + '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.14)': dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 - '@csstools/postcss-unset-value@5.0.0(postcss@8.5.13)': + '@csstools/postcss-unset-value@5.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 '@csstools/selector-resolve-nested@4.0.0(postcss-selector-parser@7.1.1)': dependencies: @@ -8171,9 +8248,9 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 - '@csstools/utilities@3.0.0(postcss@8.5.13)': + '@csstools/utilities@3.0.0(postcss@8.5.14)': dependencies: - postcss: 8.5.13 + postcss: 8.5.14 '@esbuild/aix-ppc64@0.25.12': optional: true @@ -8634,13 +8711,13 @@ snapshots: '@intlify/shared@11.2.8': {} - '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.2)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': + '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.3)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@intlify/bundle-utils': 11.0.3(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3))) '@intlify/shared': 11.2.8 '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.8)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) - '@rollup/pluginutils': 5.1.3(rollup@4.60.2) + '@rollup/pluginutils': 5.1.3(rollup@4.60.3) '@typescript-eslint/scope-manager': 8.58.0 '@typescript-eslint/typescript-estree': 8.58.0(typescript@5.9.3) debug: 4.4.3 @@ -8887,128 +8964,122 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.13': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(rollup@4.60.2)': + '@rollup/plugin-babel@6.1.0(@babel/core@7.26.0)(rollup@4.60.3)': dependencies: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 - '@rollup/pluginutils': 3.1.0(rollup@4.60.2) - rollup: 4.60.2 + '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + optionalDependencies: + rollup: 4.60.3 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@15.2.3(rollup@4.60.2)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.3)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.60.2) + '@rollup/pluginutils': 5.1.3(rollup@4.60.3) '@types/resolve': 1.20.2 deepmerge: 4.3.1 - is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 4.60.2 + rollup: 4.60.3 - '@rollup/plugin-replace@2.4.2(rollup@4.60.2)': + '@rollup/plugin-replace@6.0.3(rollup@4.60.3)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@4.60.2) - magic-string: 0.25.9 - rollup: 4.60.2 + '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.60.3 - '@rollup/plugin-terser@0.4.4(rollup@4.60.2)': + '@rollup/plugin-terser@1.0.0(rollup@4.60.3)': dependencies: serialize-javascript: 7.0.5 smob: 1.5.0 terser: 5.31.6 optionalDependencies: - rollup: 4.60.2 + rollup: 4.60.3 - '@rollup/pluginutils@3.1.0(rollup@4.60.2)': - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.2 - rollup: 4.60.2 - - '@rollup/pluginutils@5.1.3(rollup@4.60.2)': + '@rollup/pluginutils@5.1.3(rollup@4.60.3)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.2 + rollup: 4.60.3 - '@rollup/rollup-android-arm-eabi@4.60.2': + '@rollup/rollup-android-arm-eabi@4.60.3': optional: true - '@rollup/rollup-android-arm64@4.60.2': + '@rollup/rollup-android-arm64@4.60.3': optional: true - '@rollup/rollup-darwin-arm64@4.60.2': + '@rollup/rollup-darwin-arm64@4.60.3': optional: true - '@rollup/rollup-darwin-x64@4.60.2': + '@rollup/rollup-darwin-x64@4.60.3': optional: true - '@rollup/rollup-freebsd-arm64@4.60.2': + '@rollup/rollup-freebsd-arm64@4.60.3': optional: true - '@rollup/rollup-freebsd-x64@4.60.2': + '@rollup/rollup-freebsd-x64@4.60.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + '@rollup/rollup-linux-arm-gnueabihf@4.60.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.2': + '@rollup/rollup-linux-arm-musleabihf@4.60.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.2': + '@rollup/rollup-linux-arm64-gnu@4.60.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.2': + '@rollup/rollup-linux-arm64-musl@4.60.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.2': + '@rollup/rollup-linux-loong64-gnu@4.60.3': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.2': + '@rollup/rollup-linux-loong64-musl@4.60.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.2': + '@rollup/rollup-linux-ppc64-gnu@4.60.3': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.2': + '@rollup/rollup-linux-ppc64-musl@4.60.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.2': + '@rollup/rollup-linux-riscv64-gnu@4.60.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.2': + '@rollup/rollup-linux-riscv64-musl@4.60.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.2': + '@rollup/rollup-linux-s390x-gnu@4.60.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.2': + '@rollup/rollup-linux-x64-gnu@4.60.3': optional: true - '@rollup/rollup-linux-x64-musl@4.60.2': + '@rollup/rollup-linux-x64-musl@4.60.3': optional: true - '@rollup/rollup-openbsd-x64@4.60.2': + '@rollup/rollup-openbsd-x64@4.60.3': optional: true - '@rollup/rollup-openharmony-arm64@4.60.2': + '@rollup/rollup-openharmony-arm64@4.60.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.2': + '@rollup/rollup-win32-arm64-msvc@4.60.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.2': + '@rollup/rollup-win32-ia32-msvc@4.60.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.2': + '@rollup/rollup-win32-x64-gnu@4.60.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.2': + '@rollup/rollup-win32-x64-msvc@4.60.3': optional: true '@sentry-internal/browser-utils@10.36.0': @@ -9154,13 +9225,6 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@surma/rollup-plugin-off-main-thread@2.2.3': - dependencies: - ejs: 3.1.10 - json5: 2.2.3 - magic-string: 0.25.9 - string.prototype.matchall: 4.0.11 - '@tailwindcss/node@4.2.4': dependencies: '@jridgewell/remapping': 2.3.5 @@ -9433,6 +9497,13 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@trickfilm400/rollup-plugin-off-main-thread@3.0.0-pre1': + dependencies: + ejs: 3.1.10 + json5: 2.2.3 + magic-string: 0.30.21 + string.prototype.matchall: 4.0.12 + '@tsconfig/node24@24.0.4': {} '@types/chai@5.2.2': @@ -9445,8 +9516,6 @@ snapshots: '@types/deep-eql@4.0.2': {} - '@types/estree@0.0.39': {} - '@types/estree@1.0.8': {} '@types/fs-extra@11.0.4': @@ -9528,14 +9597,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.59.1 - '@typescript-eslint/type-utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.2 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9556,12 +9625,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.1 - '@typescript-eslint/types': 8.59.1 - '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.2 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 @@ -9570,8 +9639,8 @@ snapshots: '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9579,17 +9648,17 @@ snapshots: '@typescript-eslint/project-service@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.59.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) - '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9605,10 +9674,10 @@ snapshots: '@typescript-eslint/types': 8.58.0 '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/scope-manager@8.59.1': + '@typescript-eslint/scope-manager@8.59.2': dependencies: - '@typescript-eslint/types': 8.59.1 - '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: @@ -9618,11 +9687,11 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -9638,11 +9707,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.59.1 - '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -9654,10 +9723,10 @@ snapshots: '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/types@8.59.0': {} - '@typescript-eslint/types@8.59.1': {} + '@typescript-eslint/types@8.59.2': {} + '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) @@ -9688,12 +9757,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.59.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.59.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) - '@typescript-eslint/types': 8.59.1 - '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/project-service': 8.59.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.3 @@ -9725,12 +9794,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.59.1 - '@typescript-eslint/types': 8.59.1 - '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9746,9 +9815,9 @@ snapshots: '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.0 - '@typescript-eslint/visitor-keys@8.59.1': + '@typescript-eslint/visitor-keys@8.59.2': dependencies: - '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/types': 8.59.2 eslint-visitor-keys: 5.0.0 '@ungap/structured-clone@1.3.0': {} @@ -9864,7 +9933,7 @@ snapshots: '@vue/shared': 3.5.27 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.13 + postcss: 8.5.14 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.27': @@ -9907,11 +9976,11 @@ snapshots: '@vue/devtools-shared@8.1.1': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) @@ -10054,21 +10123,20 @@ snapshots: argparse@2.0.1: {} - array-buffer-byte-length@1.0.1: + array-buffer-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 + call-bound: 1.0.4 + is-array-buffer: 3.0.5 - arraybuffer.prototype.slice@1.0.3: + arraybuffer.prototype.slice@1.0.4: dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.2 es-errors: 1.3.0 get-intrinsic: 1.3.0 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 + is-array-buffer: 3.0.5 arrify@1.0.1: {} @@ -10078,6 +10146,8 @@ snapshots: astral-regex@2.0.0: {} + async-function@1.0.0: {} + async@3.2.6: {} asynckit@0.4.0: {} @@ -10089,13 +10159,13 @@ snapshots: stubborn-fs: 2.0.0 when-exit: 2.1.5 - autoprefixer@10.5.0(postcss@8.5.13): + autoprefixer@10.5.0(postcss@8.5.14): dependencies: browserslist: 4.28.2 caniuse-lite: 1.0.30001791 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -10225,8 +10295,6 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - builtin-modules@3.3.0: {} - bulma-css-variables@0.9.33: {} bundle-name@4.1.0: @@ -10248,11 +10316,10 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.7: + call-bind@1.0.9: dependencies: + call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 - es-errors: 1.3.0 - function-bind: 1.1.2 get-intrinsic: 1.3.0 set-function-length: 1.2.2 @@ -10425,23 +10492,23 @@ snapshots: crypto-random-string@2.0.0: {} - css-blank-pseudo@8.0.1(postcss@8.5.13): + css-blank-pseudo@8.0.1(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 css-functions-list@3.3.3: {} - css-has-pseudo@8.0.0(postcss@8.5.13): + css-has-pseudo@8.0.0(postcss@8.5.14): dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - css-prefers-color-scheme@11.0.0(postcss@8.5.13): + css-prefers-color-scheme@11.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 css-property-sort-order-smacss@2.2.0: {} @@ -10494,23 +10561,23 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 - data-view-buffer@1.0.1: + data-view-buffer@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-length@1.0.1: + data-view-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-offset@1.0.0: + data-view-byte-offset@1.0.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 dayjs@1.11.19: {} @@ -10683,54 +10750,62 @@ snapshots: error-stack-parser-es@1.0.5: {} - es-abstract@1.23.3: + es-abstract@1.24.2: dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - data-view-buffer: 1.0.1 - data-view-byte-length: 1.0.1 - data-view-byte-offset: 1.0.0 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 es-define-property: 1.0.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-set-tostringtag: 2.1.0 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.6 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 get-intrinsic: 1.3.0 - get-symbol-description: 1.0.2 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 globalthis: 1.0.4 gopd: 1.2.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 + has-proto: 1.2.0 has-symbols: 1.1.0 hasown: 2.0.2 - internal-slot: 1.0.7 - is-array-buffer: 3.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 is-callable: 1.2.7 - is-data-view: 1.0.1 + is-data-view: 1.0.2 is-negative-zero: 2.0.3 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 - is-typed-array: 1.1.13 - is-weakref: 1.0.2 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 object-inspect: 1.13.4 object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.2 - safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.9 - string.prototype.trimend: 1.0.8 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.2 - typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.6 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.15 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 es-define-property@1.0.1: {} @@ -10751,7 +10826,7 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - es-to-primitive@1.2.1: + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 @@ -10869,7 +10944,7 @@ snapshots: module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): + eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) eslint: 9.39.4(jiti@2.6.1) @@ -10880,7 +10955,7 @@ snapshots: vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: @@ -10958,8 +11033,6 @@ snapshots: estraverse@5.3.0: {} - estree-walker@1.0.1: {} - estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -10968,6 +11041,8 @@ snapshots: esutils@2.0.3: {} + eta@4.6.0: {} + expect-type@1.3.0: {} extend-shallow@2.0.1: @@ -11093,6 +11168,10 @@ snapshots: dependencies: is-callable: 1.2.7 + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -11131,17 +11210,21 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.6: + function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.3 functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 functions-have-names@1.2.3: {} fuse.js@7.1.0: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -11172,9 +11255,9 @@ snapshots: dependencies: pump: 3.0.0 - get-symbol-description@1.0.2: + get-symbol-description@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 @@ -11299,7 +11382,9 @@ snapshots: dependencies: es-define-property: 1.0.1 - has-proto@1.0.3: {} + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 has-symbols@1.1.0: {} @@ -11477,7 +11562,7 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 - internal-slot@1.0.7: + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 @@ -11488,14 +11573,23 @@ snapshots: jsbn: 1.1.0 sprintf-js: 1.1.3 - is-array-buffer@3.0.4: + is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 get-intrinsic: 1.3.0 is-arrayish@0.2.1: {} - is-bigint@1.0.4: + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: dependencies: has-bigints: 1.0.2 @@ -11503,29 +11597,32 @@ snapshots: dependencies: binary-extensions: 2.3.0 - is-boolean-object@1.1.2: + is-boolean-object@1.2.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-builtin-module@3.2.1: - dependencies: - builtin-modules: 3.3.0 - is-callable@1.2.7: {} is-core-module@2.15.1: dependencies: hasown: 2.0.2 - is-data-view@1.0.1: + is-data-view@1.0.2: dependencies: - is-typed-array: 1.1.13 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 is-date-object@1.0.5: dependencies: has-tostringtag: 1.0.2 + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-docker@2.2.1: {} is-docker@3.0.0: {} @@ -11534,8 +11631,20 @@ snapshots: is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -11553,14 +11662,17 @@ snapshots: is-interactive@1.0.0: {} + is-map@2.0.3: {} + is-module@1.0.0: {} is-negative-zero@2.0.3: {} is-npm@6.1.0: {} - is-number-object@1.0.7: + is-number-object@1.1.1: dependencies: + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -11575,38 +11687,56 @@ snapshots: is-potential-custom-element-name@1.0.1: {} - is-regex@1.1.4: + is-regex@1.2.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 + gopd: 1.2.0 has-tostringtag: 1.0.2 + hasown: 2.0.2 is-regexp@1.0.0: {} - is-shared-array-buffer@1.0.3: + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 is-stream@2.0.1: {} - is-string@1.0.7: + is-string@1.1.1: dependencies: + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-symbol@1.0.4: dependencies: has-symbols: 1.1.0 + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + is-touch-device@1.0.1: {} - is-typed-array@1.1.13: + is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.15 + which-typed-array: 1.1.20 is-unicode-supported@0.1.0: {} - is-weakref@1.0.2: + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 is-what@4.1.16: {} @@ -11865,10 +11995,6 @@ snapshots: lru-cache@7.18.3: {} - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -12047,10 +12173,12 @@ snapshots: object-keys@1.1.1: {} - object.assign@4.1.5: + object.assign@4.1.7: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 + es-object-atoms: 1.1.1 has-symbols: 1.1.0 object-keys: 1.1.1 @@ -12123,6 +12251,12 @@ snapshots: '@otplib/preset-default': 12.0.1 '@otplib/preset-v11': 12.0.1 + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -12240,72 +12374,72 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-attribute-case-insensitive@8.0.0(postcss@8.5.13): + postcss-attribute-case-insensitive@8.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-clamp@4.1.0(postcss@8.5.13): + postcss-clamp@4.1.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@8.0.3(postcss@8.5.13): + postcss-color-functional-notation@8.0.3(postcss@8.5.14): dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - postcss-color-hex-alpha@11.0.0(postcss@8.5.13): + postcss-color-hex-alpha@11.0.0(postcss@8.5.14): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@11.0.0(postcss@8.5.13): + postcss-color-rebeccapurple@11.0.0(postcss@8.5.14): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-custom-media@12.0.1(postcss@8.5.13): + postcss-custom-media@12.0.1(postcss@8.5.14): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.13 + postcss: 8.5.14 - postcss-custom-properties@15.0.1(postcss@8.5.13): + postcss-custom-properties@15.0.1(postcss@8.5.14): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-custom-selectors@9.0.1(postcss@8.5.13): + postcss-custom-selectors@9.0.1(postcss@8.5.14): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-dir-pseudo-class@10.0.0(postcss@8.5.13): + postcss-dir-pseudo-class@10.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-double-position-gradients@7.0.0(postcss@8.5.13): + postcss-double-position-gradients@7.0.0(postcss@8.5.14): dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 postcss-easing-gradients@3.0.1: @@ -12315,181 +12449,181 @@ snapshots: postcss: 7.0.39 postcss-value-parser: 3.3.1 - postcss-focus-visible@11.0.0(postcss@8.5.13): + postcss-focus-visible@11.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-focus-within@10.0.0(postcss@8.5.13): + postcss-focus-within@10.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-font-variant@5.0.0(postcss@8.5.13): + postcss-font-variant@5.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-gap-properties@7.0.0(postcss@8.5.13): + postcss-gap-properties@7.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-html@1.8.1: dependencies: htmlparser2: 8.0.2 js-tokens: 9.0.1 - postcss: 8.5.13 - postcss-safe-parser: 6.0.0(postcss@8.5.13) + postcss: 8.5.14 + postcss-safe-parser: 6.0.0(postcss@8.5.14) - postcss-image-set-function@8.0.0(postcss@8.5.13): + postcss-image-set-function@8.0.0(postcss@8.5.14): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-lab-function@8.0.3(postcss@8.5.13): + postcss-lab-function@8.0.3(postcss@8.5.14): dependencies: '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/utilities': 3.0.0(postcss@8.5.13) - postcss: 8.5.13 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 - postcss-logical@9.0.0(postcss@8.5.13): + postcss-logical@9.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 postcss-media-query-parser@0.2.3: {} - postcss-nesting@14.0.0(postcss@8.5.13): + postcss-nesting@14.0.0(postcss@8.5.14): dependencies: '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-opacity-percentage@3.0.0(postcss@8.5.13): + postcss-opacity-percentage@3.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-overflow-shorthand@7.0.0(postcss@8.5.13): + postcss-overflow-shorthand@7.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.13): + postcss-page-break@3.0.4(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-place@11.0.0(postcss@8.5.13): + postcss-place@11.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-preset-env@11.2.1(postcss@8.5.13): + postcss-preset-env@11.2.1(postcss@8.5.14): dependencies: - '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.13) - '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.13) - '@csstools/postcss-color-function': 5.0.3(postcss@8.5.13) - '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.13) - '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.13) - '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.13) - '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.13) - '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.13) - '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.13) - '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.13) - '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.13) - '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.13) - '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.13) - '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.13) - '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.13) - '@csstools/postcss-initial': 3.0.0(postcss@8.5.13) - '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.13) - '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.13) - '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.13) - '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.13) - '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.13) - '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.13) - '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.13) - '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.13) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.13) - '@csstools/postcss-mixins': 1.0.0(postcss@8.5.13) - '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.13) - '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.13) - '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.13) - '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.13) - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.13) - '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.13) - '@csstools/postcss-random-function': 3.0.2(postcss@8.5.13) - '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.13) - '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.13) - '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.13) - '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.13) - '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.13) - '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.13) - '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.13) - '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.13) - '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.13) - autoprefixer: 10.5.0(postcss@8.5.13) + '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.14) + '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.14) + '@csstools/postcss-color-function': 5.0.3(postcss@8.5.14) + '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.14) + '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.14) + '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.14) + '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.14) + '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.14) + '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.14) + '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.14) + '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.14) + '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.14) + '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.14) + '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.14) + '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.14) + '@csstools/postcss-initial': 3.0.0(postcss@8.5.14) + '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.14) + '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.14) + '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.14) + '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.14) + '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.14) + '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.14) + '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.14) + '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.14) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.14) + '@csstools/postcss-mixins': 1.0.0(postcss@8.5.14) + '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.14) + '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.14) + '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.14) + '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.14) + '@csstools/postcss-random-function': 3.0.2(postcss@8.5.14) + '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.14) + '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.14) + '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.14) + '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.14) + '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.14) + '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.14) + '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.14) + '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.14) + '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.14) + autoprefixer: 10.5.0(postcss@8.5.14) browserslist: 4.28.2 - css-blank-pseudo: 8.0.1(postcss@8.5.13) - css-has-pseudo: 8.0.0(postcss@8.5.13) - css-prefers-color-scheme: 11.0.0(postcss@8.5.13) + css-blank-pseudo: 8.0.1(postcss@8.5.14) + css-has-pseudo: 8.0.0(postcss@8.5.14) + css-prefers-color-scheme: 11.0.0(postcss@8.5.14) cssdb: 8.8.0 - postcss: 8.5.13 - postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.13) - postcss-clamp: 4.1.0(postcss@8.5.13) - postcss-color-functional-notation: 8.0.3(postcss@8.5.13) - postcss-color-hex-alpha: 11.0.0(postcss@8.5.13) - postcss-color-rebeccapurple: 11.0.0(postcss@8.5.13) - postcss-custom-media: 12.0.1(postcss@8.5.13) - postcss-custom-properties: 15.0.1(postcss@8.5.13) - postcss-custom-selectors: 9.0.1(postcss@8.5.13) - postcss-dir-pseudo-class: 10.0.0(postcss@8.5.13) - postcss-double-position-gradients: 7.0.0(postcss@8.5.13) - postcss-focus-visible: 11.0.0(postcss@8.5.13) - postcss-focus-within: 10.0.0(postcss@8.5.13) - postcss-font-variant: 5.0.0(postcss@8.5.13) - postcss-gap-properties: 7.0.0(postcss@8.5.13) - postcss-image-set-function: 8.0.0(postcss@8.5.13) - postcss-lab-function: 8.0.3(postcss@8.5.13) - postcss-logical: 9.0.0(postcss@8.5.13) - postcss-nesting: 14.0.0(postcss@8.5.13) - postcss-opacity-percentage: 3.0.0(postcss@8.5.13) - postcss-overflow-shorthand: 7.0.0(postcss@8.5.13) - postcss-page-break: 3.0.4(postcss@8.5.13) - postcss-place: 11.0.0(postcss@8.5.13) - postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.13) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.13) - postcss-selector-not: 9.0.0(postcss@8.5.13) + postcss: 8.5.14 + postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.14) + postcss-clamp: 4.1.0(postcss@8.5.14) + postcss-color-functional-notation: 8.0.3(postcss@8.5.14) + postcss-color-hex-alpha: 11.0.0(postcss@8.5.14) + postcss-color-rebeccapurple: 11.0.0(postcss@8.5.14) + postcss-custom-media: 12.0.1(postcss@8.5.14) + postcss-custom-properties: 15.0.1(postcss@8.5.14) + postcss-custom-selectors: 9.0.1(postcss@8.5.14) + postcss-dir-pseudo-class: 10.0.0(postcss@8.5.14) + postcss-double-position-gradients: 7.0.0(postcss@8.5.14) + postcss-focus-visible: 11.0.0(postcss@8.5.14) + postcss-focus-within: 10.0.0(postcss@8.5.14) + postcss-font-variant: 5.0.0(postcss@8.5.14) + postcss-gap-properties: 7.0.0(postcss@8.5.14) + postcss-image-set-function: 8.0.0(postcss@8.5.14) + postcss-lab-function: 8.0.3(postcss@8.5.14) + postcss-logical: 9.0.0(postcss@8.5.14) + postcss-nesting: 14.0.0(postcss@8.5.14) + postcss-opacity-percentage: 3.0.0(postcss@8.5.14) + postcss-overflow-shorthand: 7.0.0(postcss@8.5.14) + postcss-page-break: 3.0.4(postcss@8.5.14) + postcss-place: 11.0.0(postcss@8.5.14) + postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.14) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.14) + postcss-selector-not: 9.0.0(postcss@8.5.14) - postcss-pseudo-class-any-link@11.0.0(postcss@8.5.13): + postcss-pseudo-class-any-link@11.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.13): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@6.0.0(postcss@8.5.13): + postcss-safe-parser@6.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-safe-parser@7.0.1(postcss@8.5.13): + postcss-safe-parser@7.0.1(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-scss@4.0.9(postcss@8.5.13): + postcss-scss@4.0.9(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 - postcss-selector-not@9.0.0(postcss@8.5.13): + postcss-selector-not@9.0.0(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 postcss-selector-parser@7.1.1: @@ -12497,9 +12631,9 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sorting@8.0.2(postcss@8.5.13): + postcss-sorting@8.0.2(postcss@8.5.14): dependencies: - postcss: 8.5.13 + postcss: 8.5.14 postcss-value-parser@3.3.1: {} @@ -12510,7 +12644,7 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.5.13: + postcss@8.5.14: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -12735,6 +12869,17 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -12757,11 +12902,13 @@ snapshots: dependencies: regex-utilities: 2.3.0 - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 define-properties: 1.2.1 es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 set-function-name: 2.0.2 regexpu-core@6.1.1: @@ -12810,44 +12957,44 @@ snapshots: rfdc@1.4.1: {} - rollup-plugin-visualizer@6.0.11(rollup@4.60.2): + rollup-plugin-visualizer@6.0.11(rollup@4.60.3): dependencies: open: 8.4.2 picomatch: 4.0.4 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.60.2 + rollup: 4.60.3 - rollup@4.60.2: + rollup@4.60.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.2 - '@rollup/rollup-android-arm64': 4.60.2 - '@rollup/rollup-darwin-arm64': 4.60.2 - '@rollup/rollup-darwin-x64': 4.60.2 - '@rollup/rollup-freebsd-arm64': 4.60.2 - '@rollup/rollup-freebsd-x64': 4.60.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 - '@rollup/rollup-linux-arm-musleabihf': 4.60.2 - '@rollup/rollup-linux-arm64-gnu': 4.60.2 - '@rollup/rollup-linux-arm64-musl': 4.60.2 - '@rollup/rollup-linux-loong64-gnu': 4.60.2 - '@rollup/rollup-linux-loong64-musl': 4.60.2 - '@rollup/rollup-linux-ppc64-gnu': 4.60.2 - '@rollup/rollup-linux-ppc64-musl': 4.60.2 - '@rollup/rollup-linux-riscv64-gnu': 4.60.2 - '@rollup/rollup-linux-riscv64-musl': 4.60.2 - '@rollup/rollup-linux-s390x-gnu': 4.60.2 - '@rollup/rollup-linux-x64-gnu': 4.60.2 - '@rollup/rollup-linux-x64-musl': 4.60.2 - '@rollup/rollup-openbsd-x64': 4.60.2 - '@rollup/rollup-openharmony-arm64': 4.60.2 - '@rollup/rollup-win32-arm64-msvc': 4.60.2 - '@rollup/rollup-win32-ia32-msvc': 4.60.2 - '@rollup/rollup-win32-x64-gnu': 4.60.2 - '@rollup/rollup-win32-x64-msvc': 4.60.2 + '@rollup/rollup-android-arm-eabi': 4.60.3 + '@rollup/rollup-android-arm64': 4.60.3 + '@rollup/rollup-darwin-arm64': 4.60.3 + '@rollup/rollup-darwin-x64': 4.60.3 + '@rollup/rollup-freebsd-arm64': 4.60.3 + '@rollup/rollup-freebsd-x64': 4.60.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.3 + '@rollup/rollup-linux-arm-musleabihf': 4.60.3 + '@rollup/rollup-linux-arm64-gnu': 4.60.3 + '@rollup/rollup-linux-arm64-musl': 4.60.3 + '@rollup/rollup-linux-loong64-gnu': 4.60.3 + '@rollup/rollup-linux-loong64-musl': 4.60.3 + '@rollup/rollup-linux-ppc64-gnu': 4.60.3 + '@rollup/rollup-linux-ppc64-musl': 4.60.3 + '@rollup/rollup-linux-riscv64-gnu': 4.60.3 + '@rollup/rollup-linux-riscv64-musl': 4.60.3 + '@rollup/rollup-linux-s390x-gnu': 4.60.3 + '@rollup/rollup-linux-x64-gnu': 4.60.3 + '@rollup/rollup-linux-x64-musl': 4.60.3 + '@rollup/rollup-openbsd-x64': 4.60.3 + '@rollup/rollup-openharmony-arm64': 4.60.3 + '@rollup/rollup-win32-arm64-msvc': 4.60.3 + '@rollup/rollup-win32-ia32-msvc': 4.60.3 + '@rollup/rollup-win32-x64-gnu': 4.60.3 + '@rollup/rollup-win32-x64-msvc': 4.60.3 fsevents: 2.3.3 rope-sequence@1.3.4: {} @@ -12872,20 +13019,26 @@ snapshots: dependencies: mri: 1.2.0 - safe-array-concat@1.1.2: + safe-array-concat@1.1.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 get-intrinsic: 1.3.0 has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.2.1: {} - safe-regex-test@1.0.3: + safe-push-apply@1.0.0: dependencies: - call-bind: 1.0.7 es-errors: 1.3.0 - is-regex: 1.1.4 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 safer-buffer@2.1.2: {} @@ -13020,6 +13173,12 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -13123,8 +13282,6 @@ snapshots: dependencies: whatwg-url: 7.1.0 - sourcemap-codec@1.4.8: {} - space-separated-tokens@2.0.2: {} spdx-correct@3.2.0: @@ -13153,6 +13310,11 @@ snapshots: std-env@4.0.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + streamx@2.22.0: dependencies: fast-fifo: 1.3.2 @@ -13183,37 +13345,42 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 - string.prototype.matchall@4.0.11: + string.prototype.matchall@4.0.12: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 gopd: 1.2.0 has-symbols: 1.1.0 - internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 set-function-name: 2.0.2 side-channel: 1.1.0 - string.prototype.trim@1.2.9: + string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 - string.prototype.trimend@1.0.8: + string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -13271,14 +13438,14 @@ snapshots: stylelint: 17.10.0(typescript@5.9.3) stylelint-order: 6.0.4(stylelint@17.10.0(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.5.13) + postcss-scss: 4.0.9(postcss@8.5.14) stylelint: 17.10.0(typescript@5.9.3) stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) stylelint-scss: 7.0.0(stylelint@17.10.0(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.13 + postcss: 8.5.14 stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)): dependencies: @@ -13292,13 +13459,13 @@ snapshots: dependencies: stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)): dependencies: stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.13)(stylelint@17.10.0(typescript@5.9.3)) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)) stylelint-config-standard: 40.0.0(stylelint@17.10.0(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.13 + postcss: 8.5.14 stylelint-config-standard@40.0.0(stylelint@17.10.0(typescript@5.9.3)): dependencies: @@ -13307,8 +13474,8 @@ snapshots: stylelint-order@6.0.4(stylelint@17.10.0(typescript@5.9.3)): dependencies: - postcss: 8.5.13 - postcss-sorting: 8.0.2(postcss@8.5.13) + postcss: 8.5.14 + postcss-sorting: 8.0.2(postcss@8.5.14) stylelint: 17.10.0(typescript@5.9.3) stylelint-scss@7.0.0(stylelint@17.10.0(typescript@5.9.3)): @@ -13356,8 +13523,8 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.13 - postcss-safe-parser: 7.0.1(postcss@8.5.13) + postcss: 8.5.14 + postcss-safe-parser: 7.0.1(postcss@8.5.14) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 string-width: 8.2.0 @@ -13545,37 +13712,38 @@ snapshots: type-fest@4.41.0: {} - typed-array-buffer@1.0.2: + typed-array-buffer@1.0.3: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 es-errors: 1.3.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: + typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 for-each: 0.3.3 gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + has-proto: 1.2.0 + is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.2: + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 + call-bind: 1.0.9 for-each: 0.3.3 gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 - typed-array-length@1.0.6: + typed-array-length@1.0.7: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 for-each: 0.3.3 gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 possible-typed-array-names: 1.0.0 + reflect.getprototypeof: 1.0.10 typed-query-selector@2.12.0: {} @@ -13596,12 +13764,12 @@ snapshots: ufo@1.6.3: {} - unbox-primitive@1.0.2: + unbox-primitive@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.4 has-bigints: 1.0.2 has-symbols: 1.1.0 - which-boxed-primitive: 1.0.2 + which-boxed-primitive: 1.1.1 unbzip2-stream@1.4.3: dependencies: @@ -13780,14 +13948,14 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - workbox-build: 7.4.0 - workbox-window: 7.4.0 + workbox-build: 7.4.1 + workbox-window: 7.4.1 transitivePeerDependencies: - supports-color @@ -13833,8 +14001,8 @@ snapshots: esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.13 - rollup: 4.60.2 + postcss: 8.5.14 + rollup: 4.60.3 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.12.2 @@ -13999,19 +14167,44 @@ snapshots: when-exit@2.1.5: {} - which-boxed-primitive@1.0.2: + which-boxed-primitive@1.1.1: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 - which-typed-array@1.1.15: + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 gopd: 1.2.0 has-tostringtag: 1.0.2 @@ -14034,63 +14227,63 @@ snapshots: word-wrap@1.2.5: {} - workbox-background-sync@7.4.0: + workbox-background-sync@7.4.1: dependencies: idb: 7.1.1 - workbox-core: 7.4.0 + workbox-core: 7.4.1 - workbox-broadcast-update@7.4.0: + workbox-broadcast-update@7.4.1: dependencies: - workbox-core: 7.4.0 + workbox-core: 7.4.1 - workbox-build@7.4.0: + workbox-build@7.4.1: dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.18.0) '@babel/core': 7.26.0 '@babel/preset-env': 7.26.0(@babel/core@7.26.0) '@babel/runtime': 7.25.4 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(rollup@4.60.2) - '@rollup/plugin-node-resolve': 15.2.3(rollup@4.60.2) - '@rollup/plugin-replace': 2.4.2(rollup@4.60.2) - '@rollup/plugin-terser': 0.4.4(rollup@4.60.2) - '@surma/rollup-plugin-off-main-thread': 2.2.3 + '@rollup/plugin-babel': 6.1.0(@babel/core@7.26.0)(rollup@4.60.3) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.3) + '@rollup/plugin-replace': 6.0.3(rollup@4.60.3) + '@rollup/plugin-terser': 1.0.0(rollup@4.60.3) + '@trickfilm400/rollup-plugin-off-main-thread': 3.0.0-pre1 ajv: 8.18.0 common-tags: 1.8.2 + eta: 4.6.0 fast-json-stable-stringify: 2.1.0 fs-extra: 9.1.0 glob: 11.1.0 - lodash: 4.18.1 pretty-bytes: 5.6.0 - rollup: 4.60.2 + rollup: 4.60.3 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 tempy: 0.6.0 upath: 1.2.0 - workbox-background-sync: 7.4.0 - workbox-broadcast-update: 7.4.0 - workbox-cacheable-response: 7.4.0 - workbox-core: 7.4.0 - workbox-expiration: 7.4.0 - workbox-google-analytics: 7.4.0 - workbox-navigation-preload: 7.4.0 - workbox-precaching: 7.4.0 - workbox-range-requests: 7.4.0 - workbox-recipes: 7.4.0 - workbox-routing: 7.4.0 - workbox-strategies: 7.4.0 - workbox-streams: 7.4.0 - workbox-sw: 7.4.0 - workbox-window: 7.4.0 + workbox-background-sync: 7.4.1 + workbox-broadcast-update: 7.4.1 + workbox-cacheable-response: 7.4.1 + workbox-core: 7.4.1 + workbox-expiration: 7.4.1 + workbox-google-analytics: 7.4.1 + workbox-navigation-preload: 7.4.1 + workbox-precaching: 7.4.1 + workbox-range-requests: 7.4.1 + workbox-recipes: 7.4.1 + workbox-routing: 7.4.1 + workbox-strategies: 7.4.1 + workbox-streams: 7.4.1 + workbox-sw: 7.4.1 + workbox-window: 7.4.1 transitivePeerDependencies: - '@types/babel__core' - supports-color - workbox-cacheable-response@7.4.0: + workbox-cacheable-response@7.4.1: dependencies: - workbox-core: 7.4.0 + workbox-core: 7.4.1 - workbox-cli@7.4.0: + workbox-cli@7.4.1: dependencies: chalk: 4.1.2 chokidar: 3.6.0 @@ -14104,28 +14297,30 @@ snapshots: stringify-object: 3.3.0 upath: 1.2.0 update-notifier: 7.3.1 - workbox-build: 7.4.0 + workbox-build: 7.4.1 transitivePeerDependencies: - '@types/babel__core' - supports-color workbox-core@7.4.0: {} - workbox-expiration@7.4.0: + workbox-core@7.4.1: {} + + workbox-expiration@7.4.1: dependencies: idb: 7.1.1 - workbox-core: 7.4.0 + workbox-core: 7.4.1 - workbox-google-analytics@7.4.0: + workbox-google-analytics@7.4.1: dependencies: - workbox-background-sync: 7.4.0 - workbox-core: 7.4.0 - workbox-routing: 7.4.0 - workbox-strategies: 7.4.0 + workbox-background-sync: 7.4.1 + workbox-core: 7.4.1 + workbox-routing: 7.4.1 + workbox-strategies: 7.4.1 - workbox-navigation-preload@7.4.0: + workbox-navigation-preload@7.4.1: dependencies: - workbox-core: 7.4.0 + workbox-core: 7.4.1 workbox-precaching@7.4.0: dependencies: @@ -14133,38 +14328,52 @@ snapshots: workbox-routing: 7.4.0 workbox-strategies: 7.4.0 - workbox-range-requests@7.4.0: + workbox-precaching@7.4.1: dependencies: - workbox-core: 7.4.0 + workbox-core: 7.4.1 + workbox-routing: 7.4.1 + workbox-strategies: 7.4.1 - workbox-recipes@7.4.0: + workbox-range-requests@7.4.1: dependencies: - workbox-cacheable-response: 7.4.0 - workbox-core: 7.4.0 - workbox-expiration: 7.4.0 - workbox-precaching: 7.4.0 - workbox-routing: 7.4.0 - workbox-strategies: 7.4.0 + workbox-core: 7.4.1 + + workbox-recipes@7.4.1: + dependencies: + workbox-cacheable-response: 7.4.1 + workbox-core: 7.4.1 + workbox-expiration: 7.4.1 + workbox-precaching: 7.4.1 + workbox-routing: 7.4.1 + workbox-strategies: 7.4.1 workbox-routing@7.4.0: dependencies: workbox-core: 7.4.0 + workbox-routing@7.4.1: + dependencies: + workbox-core: 7.4.1 + workbox-strategies@7.4.0: dependencies: workbox-core: 7.4.0 - workbox-streams@7.4.0: + workbox-strategies@7.4.1: dependencies: - workbox-core: 7.4.0 - workbox-routing: 7.4.0 + workbox-core: 7.4.1 - workbox-sw@7.4.0: {} + workbox-streams@7.4.1: + dependencies: + workbox-core: 7.4.1 + workbox-routing: 7.4.1 - workbox-window@7.4.0: + workbox-sw@7.4.1: {} + + workbox-window@7.4.1: dependencies: '@types/trusted-types': 2.0.7 - workbox-core: 7.4.0 + workbox-core: 7.4.1 wrap-ansi@7.0.0: dependencies: From 926e16308994a13152b6bb2fe30d1cdb5e6e5e1b Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 5 May 2026 09:15:13 +0200 Subject: [PATCH 027/313] chore(deps): bump workbox-precaching to 7.4.1 to match workbox-cli --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 32 ++------------------------------ 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 81926f33e..49e034646 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -100,7 +100,7 @@ "vue-i18n": "11.2.8", "vue-router": "4.6.4", "vuemoji-picker": "0.3.2", - "workbox-precaching": "7.4.0", + "workbox-precaching": "7.4.1", "zhyswan-vuedraggable": "4.1.3" }, "devDependencies": { diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 4ea725738..7c984cfe4 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -163,8 +163,8 @@ importers: specifier: 0.3.2 version: 0.3.2(vue@3.5.27(typescript@5.9.3)) workbox-precaching: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.4.1 + version: 7.4.1 zhyswan-vuedraggable: specifier: 4.1.3 version: 4.1.3(vue@3.5.27(typescript@5.9.3)) @@ -6973,9 +6973,6 @@ packages: engines: {node: '>=20.0.0'} hasBin: true - workbox-core@7.4.0: - resolution: {integrity: sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==} - workbox-core@7.4.1: resolution: {integrity: sha512-DT+vu46eh/2vRsSHTY4Xmc32Z1rr9PRlQUXr1Dx30ZuXRWwOsvZgGgcwxcasubQLQmbTNYZjv44LkBAQ4tT5tQ==} @@ -6988,9 +6985,6 @@ packages: workbox-navigation-preload@7.4.1: resolution: {integrity: sha512-C4KVsjPcYKJOhr631AxR9XoG2rLF3QiTk5aMv36MXOjtWvm8axwNFAtKUPGsWUwLXXAMgYM1En7fsvndaXeXRQ==} - workbox-precaching@7.4.0: - resolution: {integrity: sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==} - workbox-precaching@7.4.1: resolution: {integrity: sha512-cdr/9qByww7yzEp7zg/qI4ukUrrNjQLgN+ONQRpjy/VqGQXwkgHwr00KksGJK8v0VifwDXBb8a4cWNZH71jn3Q==} @@ -7000,15 +6994,9 @@ packages: workbox-recipes@7.4.1: resolution: {integrity: sha512-gnbVfmV4/TtmQaM4x9AtuXhcdstJsep3XMVeztOrQVPT+R6+6DeBjGTCQ7fFCXm+4GEHUA5VEBTyi5+4gWGeog==} - workbox-routing@7.4.0: - resolution: {integrity: sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==} - workbox-routing@7.4.1: resolution: {integrity: sha512-yubJGErZOusuidAenaL5ypfhQOa7urxP/f8E0ws7FPb4039RiWXUWBAyUkmUoOL/BcQGen3h0J8872d51IYxtA==} - workbox-strategies@7.4.0: - resolution: {integrity: sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==} - workbox-strategies@7.4.1: resolution: {integrity: sha512-GZxpaw9NbmOelj7667uZ2kpk5BFpOGbO4X0qjwh5ls8XQ8C+Lha5LQchTiUzsTFSS+NlUpftYAyOVXvQUrcqOQ==} @@ -14302,8 +14290,6 @@ snapshots: - '@types/babel__core' - supports-color - workbox-core@7.4.0: {} - workbox-core@7.4.1: {} workbox-expiration@7.4.1: @@ -14322,12 +14308,6 @@ snapshots: dependencies: workbox-core: 7.4.1 - workbox-precaching@7.4.0: - dependencies: - workbox-core: 7.4.0 - workbox-routing: 7.4.0 - workbox-strategies: 7.4.0 - workbox-precaching@7.4.1: dependencies: workbox-core: 7.4.1 @@ -14347,18 +14327,10 @@ snapshots: workbox-routing: 7.4.1 workbox-strategies: 7.4.1 - workbox-routing@7.4.0: - dependencies: - workbox-core: 7.4.0 - workbox-routing@7.4.1: dependencies: workbox-core: 7.4.1 - workbox-strategies@7.4.0: - dependencies: - workbox-core: 7.4.0 - workbox-strategies@7.4.1: dependencies: workbox-core: 7.4.1 From 469ee8f364850794c9c7238cf99f4af6cb1735f3 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 5 May 2026 16:17:16 +0200 Subject: [PATCH 028/313] fix(frontend): respect user's 12h/24h time format in date pickers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flatpickr time inputs hardcoded `time_24hr: true`, so users who selected the 12-hour format in their settings still got a 24-hour picker — even though the displayed dates respected the preference. Bind `time_24hr` to the existing `useTimeFormat` composable in: - DatepickerInline (start/end/due dates and absolute reminders) - DeferTask (defer due date) - ApiTokenForm (API token expiry) Reported at https://community.vikunja.io/t/4492. --- frontend/src/components/input/DatepickerInline.vue | 5 ++++- frontend/src/components/tasks/partials/DeferTask.vue | 5 ++++- frontend/src/components/token/ApiTokenForm.vue | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/input/DatepickerInline.vue b/frontend/src/components/input/DatepickerInline.vue index de6503833..9f0467889 100644 --- a/frontend/src/components/input/DatepickerInline.vue +++ b/frontend/src/components/input/DatepickerInline.vue @@ -84,6 +84,8 @@ import {calculateNearestHours} from '@/helpers/time/calculateNearestHours' import {createDateFromString} from '@/helpers/time/createDateFromString' import {useI18n} from 'vue-i18n' import {useFlatpickrLanguage} from '@/helpers/useFlatpickrLanguage' +import {useTimeFormat} from '@/composables/useTimeFormat' +import {TIME_FORMAT} from '@/constants/timeFormat' const props = defineProps<{ modelValue: Date | null | string @@ -94,6 +96,7 @@ const emit = defineEmits<{ }>() const {t} = useI18n({useScope: 'global'}) +const {store: timeFormat} = useTimeFormat() const date = ref(null) const changed = ref(false) @@ -111,7 +114,7 @@ const flatPickerConfig = computed(() => ({ altInput: true, dateFormat: 'Y-m-d H:i', enableTime: true, - time_24hr: true, + time_24hr: timeFormat.value === TIME_FORMAT.HOURS_24, inline: true, locale: useFlatpickrLanguage().value, })) diff --git a/frontend/src/components/tasks/partials/DeferTask.vue b/frontend/src/components/tasks/partials/DeferTask.vue index 6092d63c7..b29bb2a0f 100644 --- a/frontend/src/components/tasks/partials/DeferTask.vue +++ b/frontend/src/components/tasks/partials/DeferTask.vue @@ -49,6 +49,8 @@ import flatPickr from 'vue-flatpickr-component' import TaskService from '@/services/task' import type {ITask} from '@/modelTypes/ITask' import {useFlatpickrLanguage} from '@/helpers/useFlatpickrLanguage' +import {useTimeFormat} from '@/composables/useTimeFormat' +import {TIME_FORMAT} from '@/constants/timeFormat' const props = defineProps<{ modelValue: ITask, @@ -59,6 +61,7 @@ const emit = defineEmits<{ }>() const {t} = useI18n({useScope: 'global'}) +const {store: timeFormat} = useTimeFormat() const taskService = shallowReactive(new TaskService()) const task = ref() @@ -103,7 +106,7 @@ const flatPickerConfig = computed(() => ({ altInput: true, dateFormat: 'Y-m-d H:i', enableTime: true, - time_24hr: true, + time_24hr: timeFormat.value === TIME_FORMAT.HOURS_24, inline: true, locale: useFlatpickrLanguage().value, })) diff --git a/frontend/src/components/token/ApiTokenForm.vue b/frontend/src/components/token/ApiTokenForm.vue index 5de674ce0..77f6b1e22 100644 --- a/frontend/src/components/token/ApiTokenForm.vue +++ b/frontend/src/components/token/ApiTokenForm.vue @@ -11,6 +11,8 @@ import 'flatpickr/dist/flatpickr.css' import {useI18n} from 'vue-i18n' import FormField from '@/components/input/FormField.vue' import type {IApiToken} from '@/modelTypes/IApiToken' +import {useTimeFormat} from '@/composables/useTimeFormat' +import {TIME_FORMAT} from '@/constants/timeFormat' const props = withDefaults(defineProps<{ ownerId?: number, @@ -31,6 +33,7 @@ const emit = defineEmits<{ const service = new ApiTokenService() const {t} = useI18n() +const {store: timeFormat} = useTimeFormat() const now = new Date() const availableRoutes = ref(null) @@ -98,7 +101,7 @@ const flatPickerConfig = computed(() => ({ altInput: true, dateFormat: 'Y-m-d H:i', enableTime: true, - time_24hr: true, + time_24hr: timeFormat.value === TIME_FORMAT.HOURS_24, locale: useFlatpickrLanguage().value, minDate: now, })) From 1ea5675e1b58e81ac65384ac0200e3fb4b99ba75 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 5 May 2026 16:55:33 +0200 Subject: [PATCH 029/313] fix(frontend): extend checkbox hit target to 44x44 A pseudo-element on the label provides a 44x44 minimum hit area centered on the visible icon. Visible size and surrounding layout are unchanged. Addresses misclicks on the task list view checkbox where ~50% of taps would open the task detail instead of toggling done. --- frontend/src/components/base/BaseCheckbox.vue | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/src/components/base/BaseCheckbox.vue b/frontend/src/components/base/BaseCheckbox.vue index 625944490..39ad34b28 100644 --- a/frontend/src/components/base/BaseCheckbox.vue +++ b/frontend/src/components/base/BaseCheckbox.vue @@ -40,6 +40,20 @@ const emit = defineEmits<{ user-select: none; -webkit-tap-highlight-color: transparent; display: inline-flex; + position: relative; +} + +// Extend the hit target to >=44x44 without affecting layout (WCAG 2.5.5). +.base-checkbox__label::before { + content: ''; + position: absolute; + inset-block-start: 50%; + inset-inline-start: 50%; + min-block-size: 44px; + min-inline-size: 44px; + block-size: 100%; + inline-size: 100%; + transform: translate(-50%, -50%); } .base-checkbox:has(input:disabled) .base-checkbox__label { From 9bea92bb6f773ffde5a02b6dc0351f039e00c605 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 5 May 2026 16:55:38 +0200 Subject: [PATCH 030/313] fix(frontend): skip task detail on label and checkbox clicks Defense in depth for the list-view row click handler: a click that lands on a label or checkbox input no longer bubbles up to open the task detail. --- frontend/src/components/tasks/partials/SingleTaskInProject.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/tasks/partials/SingleTaskInProject.vue b/frontend/src/components/tasks/partials/SingleTaskInProject.vue index ce1b5051f..50842df29 100644 --- a/frontend/src/components/tasks/partials/SingleTaskInProject.vue +++ b/frontend/src/components/tasks/partials/SingleTaskInProject.vue @@ -383,7 +383,7 @@ function hasTextSelected() { function openTaskDetail(event: MouseEvent | KeyboardEvent) { if (event.target instanceof HTMLElement) { - const isInteractiveElement = event.target.closest('a, button, .favorite, [role="button"]') + const isInteractiveElement = event.target.closest('a, button, label, input[type="checkbox"], .favorite, [role="button"]') if (isInteractiveElement || hasTextSelected()) { return } From 3d594db725bbc2708b0c08c6ecf81c8b783d4950 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 5 May 2026 17:21:50 +0200 Subject: [PATCH 031/313] fix(frontend): scope checkbox hit-area pseudo to the task row The pseudo-element that extends the checkbox hit target also covered label text content, which broke Playwright actionability checks for clicks on text inside wider FancyCheckbox labels (e.g. the "Show Archived" toggle on the projects list page). Move the rule out of BaseCheckbox and into SingleTaskInProject's deep override, where the label slot is already hidden via display: none, so no neighboring content can be intercepted. --- frontend/src/components/base/BaseCheckbox.vue | 14 -------------- .../tasks/partials/SingleTaskInProject.vue | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/base/BaseCheckbox.vue b/frontend/src/components/base/BaseCheckbox.vue index 39ad34b28..625944490 100644 --- a/frontend/src/components/base/BaseCheckbox.vue +++ b/frontend/src/components/base/BaseCheckbox.vue @@ -40,20 +40,6 @@ const emit = defineEmits<{ user-select: none; -webkit-tap-highlight-color: transparent; display: inline-flex; - position: relative; -} - -// Extend the hit target to >=44x44 without affecting layout (WCAG 2.5.5). -.base-checkbox__label::before { - content: ''; - position: absolute; - inset-block-start: 50%; - inset-inline-start: 50%; - min-block-size: 44px; - min-inline-size: 44px; - block-size: 100%; - inline-size: 100%; - transform: translate(-50%, -50%); } .base-checkbox:has(input:disabled) .base-checkbox__label { diff --git a/frontend/src/components/tasks/partials/SingleTaskInProject.vue b/frontend/src/components/tasks/partials/SingleTaskInProject.vue index 50842df29..57a115b85 100644 --- a/frontend/src/components/tasks/partials/SingleTaskInProject.vue +++ b/frontend/src/components/tasks/partials/SingleTaskInProject.vue @@ -536,6 +536,23 @@ defineExpose({ span { display: none; } + + // Extend the hit target to >=44x44 without affecting layout (WCAG 2.5.5). + .base-checkbox__label { + position: relative; + + &::before { + content: ''; + position: absolute; + inset-block-start: 50%; + inset-inline-start: 50%; + min-block-size: 44px; + min-inline-size: 44px; + block-size: 100%; + inline-size: 100%; + transform: translate(-50%, -50%); + } + } } .tasktext.done { From 4754230ef013abe958cb83b455b5f09475a6d327 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 10:11:15 +0000 Subject: [PATCH 032/313] chore(deps): update dev-dependencies --- frontend/package.json | 8 +-- frontend/pnpm-lock.yaml | 131 ++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 69 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 49e034646..2a5343909 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -125,12 +125,12 @@ "@vueuse/shared": "14.3.0", "autoprefixer": "10.5.0", "browserslist": "4.28.2", - "caniuse-lite": "1.0.30001791", + "caniuse-lite": "1.0.30001792", "csstype": "3.2.3", "esbuild": "0.28.0", "eslint": "9.39.4", "eslint-plugin-depend": "1.5.0", - "eslint-plugin-vue": "10.9.0", + "eslint-plugin-vue": "10.9.1", "happy-dom": "20.9.0", "histoire": "1.0.0-beta.1", "otplib": "12.0.1", @@ -141,7 +141,7 @@ "rollup": "4.60.3", "rollup-plugin-visualizer": "6.0.11", "sass-embedded": "1.99.0", - "stylelint": "17.10.0", + "stylelint": "17.11.0", "stylelint-config-property-sort-order-smacss": "10.0.0", "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", @@ -150,7 +150,7 @@ "typescript": "5.9.3", "unplugin-inject-preload": "3.0.0", "vite": "7.3.2", - "vite-plugin-pwa": "1.2.0", + "vite-plugin-pwa": "1.3.0", "vite-plugin-vue-devtools": "8.1.1", "vite-svg-loader": "5.1.1", "vitest": "4.1.5", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 7c984cfe4..9184dec08 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -216,7 +216,7 @@ importers: version: 6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': specifier: 2.4.10 version: 2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) @@ -233,8 +233,8 @@ importers: specifier: 4.28.2 version: 4.28.2 caniuse-lite: - specifier: 1.0.30001791 - version: 1.0.30001791 + specifier: 1.0.30001792 + version: 1.0.30001792 csstype: specifier: 3.2.3 version: 3.2.3 @@ -248,8 +248,8 @@ importers: specifier: 1.5.0 version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: - specifier: 10.9.0 - version: 10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + specifier: 10.9.1 + version: 10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: specifier: 20.9.0 version: 20.9.0 @@ -281,20 +281,20 @@ importers: specifier: 1.99.0 version: 1.99.0 stylelint: - specifier: 17.10.0 - version: 17.10.0(typescript@5.9.3) + specifier: 17.11.0 + version: 17.11.0(typescript@5.9.3) stylelint-config-property-sort-order-smacss: specifier: 10.0.0 - version: 10.0.0(stylelint@17.10.0(typescript@5.9.3)) + version: 10.0.0(stylelint@17.11.0(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: 1.6.1 - version: 1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 - version: 2.1.3(stylelint@17.10.0(typescript@5.9.3)) + version: 2.1.3(stylelint@17.11.0(typescript@5.9.3)) tailwindcss: specifier: 4.2.4 version: 4.2.4 @@ -308,8 +308,8 @@ importers: specifier: 7.3.2 version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: - specifier: 1.2.0 - version: 1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) + specifier: 1.3.0 + version: 1.3.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) vite-plugin-vue-devtools: specifier: 8.1.1 version: 8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) @@ -3012,6 +3012,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@vitejs/plugin-vue@6.0.6': resolution: {integrity: sha512-u9HHgfrq3AjXlysn0eINFnWQOJQLO9WN6VprZ8FXl7A2bYisv3Hui9Ij+7QZ41F/WYWarHjwBbXtD7dKg3uxbg==} @@ -3459,8 +3460,8 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001791: - resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + caniuse-lite@1.0.30001792: + resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} capture-website@4.2.0: resolution: {integrity: sha512-EmkSn36CXTC8tUsS6aNmvvsdpfVTYYkuRp7U5bV9gcJwcDbqqA5c0Op/iskYPKtDdOkuVp61mjn/LLywX0h7cw==} @@ -3979,14 +3980,14 @@ packages: peerDependencies: eslint: '>=8.40.0' - eslint-plugin-vue@10.9.0: - resolution: {integrity: sha512-EFNNzu4HqtTRb5DJINpyd+u3bDdzETWDMpCzG+UBHz1tpsnMDCeOcf61u4Wy/cbXnMymK+MT9bjH7KcG1fItSw==} + eslint-plugin-vue@10.9.1: + resolution: {integrity: sha512-cHB0Tf4Duvzwecwd/AqWzZvF/QszE13BhjVUpVXWCy9AeMR5GjkAjP3i85vqgLgOuTmkHR1OJ5oMeqLHtuw8zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-eslint-parser: ^10.0.0 + vue-eslint-parser: ^10.3.0 peerDependenciesMeta: '@stylistic/eslint-plugin': optional: true @@ -6162,8 +6163,8 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.2.0: - resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} + string-width@8.2.1: + resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} engines: {node: '>=20'} string.prototype.matchall@4.0.12: @@ -6298,8 +6299,8 @@ packages: peerDependencies: stylelint: '>= 11 < 18' - stylelint@17.10.0: - resolution: {integrity: sha512-cI7I6HHEYOHHVNVci+s92WlA3QfmNhjwFdgCgYV3TLEysilOjk+B3EFxMED1xY9GYB0Kre3OD+mSLj19VLTIvA==} + stylelint@17.11.0: + resolution: {integrity: sha512-/3czzmbF9XdGWvReDF3Ex4R23Ajolo7j8RB2bFNEqk6Ht356nlpVV+G5bG2Qt8AW1ofJzXztBRDnAtd7cgowWA==} engines: {node: '>=20.19.0'} hasBin: true @@ -6678,14 +6679,14 @@ packages: '@nuxt/kit': optional: true - vite-plugin-pwa@1.2.0: - resolution: {integrity: sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==} + vite-plugin-pwa@1.3.0: + resolution: {integrity: sha512-c5kMgN+ITrOtHXp8PAtk2uOIEea6XjP/unCGxOWWBzQ6qa65qj/awHg0wf+QF9E/2u9vh86LqxPwzEPNbM2r5A==} engines: {node: '>=16.0.0'} peerDependencies: '@vite-pwa/assets-generator': ^1.0.0 - vite: ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - workbox-build: ^7.4.0 - workbox-window: ^7.4.0 + vite: ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + workbox-build: ^7.4.1 + workbox-window: ^7.4.1 peerDependenciesMeta: '@vite-pwa/assets-generator': optional: true @@ -9964,11 +9965,11 @@ snapshots: '@vue/devtools-shared@8.1.1': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-plugin-vue: 10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) @@ -10150,7 +10151,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.14): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001791 + caniuse-lite: 1.0.30001792 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.14 @@ -10269,7 +10270,7 @@ snapshots: browserslist@4.28.2: dependencies: baseline-browser-mapping: 2.10.12 - caniuse-lite: 1.0.30001791 + caniuse-lite: 1.0.30001792 electron-to-chromium: 1.5.329 node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -10328,7 +10329,7 @@ snapshots: camelcase@8.0.0: {} - caniuse-lite@1.0.30001791: {} + caniuse-lite@1.0.30001792: {} capture-website@4.2.0(typescript@5.9.3): dependencies: @@ -10932,7 +10933,7 @@ snapshots: module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): + eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) eslint: 9.39.4(jiti@2.6.1) @@ -13328,7 +13329,7 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 - string-width@8.2.0: + string-width@8.2.1: dependencies: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 @@ -13415,58 +13416,58 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 - stylelint: 17.10.0(typescript@5.9.3) + stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.11.0(typescript@5.9.3)): dependencies: css-property-sort-order-smacss: 2.2.0 - stylelint: 17.10.0(typescript@5.9.3) - stylelint-order: 6.0.4(stylelint@17.10.0(typescript@5.9.3)) + stylelint: 17.11.0(typescript@5.9.3) + stylelint-order: 6.0.4(stylelint@17.11.0(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)): dependencies: postcss-scss: 4.0.9(postcss@8.5.14) - stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) - stylelint-scss: 7.0.0(stylelint@17.10.0(typescript@5.9.3)) + stylelint: 17.11.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint-scss: 7.0.0(stylelint@17.11.0(typescript@5.9.3)) optionalDependencies: postcss: 8.5.14 - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 semver: 7.7.3 - stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.10.0(typescript@5.9.3)) - stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) + stylelint: 17.11.0(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) - stylelint-config-recommended@18.0.0(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.11.0(typescript@5.9.3)): dependencies: - stylelint: 17.10.0(typescript@5.9.3) + stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)): dependencies: - stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.14)(stylelint@17.10.0(typescript@5.9.3)) - stylelint-config-standard: 40.0.0(stylelint@17.10.0(typescript@5.9.3)) + stylelint: 17.11.0(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.11.0(typescript@5.9.3)) optionalDependencies: postcss: 8.5.14 - stylelint-config-standard@40.0.0(stylelint@17.10.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.11.0(typescript@5.9.3)): dependencies: - stylelint: 17.10.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.10.0(typescript@5.9.3)) + stylelint: 17.11.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) - stylelint-order@6.0.4(stylelint@17.10.0(typescript@5.9.3)): + stylelint-order@6.0.4(stylelint@17.11.0(typescript@5.9.3)): dependencies: postcss: 8.5.14 postcss-sorting: 8.0.2(postcss@8.5.14) - stylelint: 17.10.0(typescript@5.9.3) + stylelint: 17.11.0(typescript@5.9.3) - stylelint-scss@7.0.0(stylelint@17.10.0(typescript@5.9.3)): + stylelint-scss@7.0.0(stylelint@17.11.0(typescript@5.9.3)): dependencies: css-tree: 3.2.1 is-plain-object: 5.0.0 @@ -13476,13 +13477,13 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - stylelint: 17.10.0(typescript@5.9.3) + stylelint: 17.11.0(typescript@5.9.3) - stylelint-use-logical@2.1.3(stylelint@17.10.0(typescript@5.9.3)): + stylelint-use-logical@2.1.3(stylelint@17.11.0(typescript@5.9.3)): dependencies: - stylelint: 17.10.0(typescript@5.9.3) + stylelint: 17.11.0(typescript@5.9.3) - stylelint@17.10.0(typescript@5.9.3): + stylelint@17.11.0(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -13515,7 +13516,7 @@ snapshots: postcss-safe-parser: 7.0.1(postcss@8.5.14) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - string-width: 8.2.0 + string-width: 8.2.1 supports-hyperlinks: 4.4.0 svg-tags: 1.0.0 table: 6.9.0 @@ -13936,7 +13937,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): + vite-plugin-pwa@1.3.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 From fc9a9a6c71e66588ad5a63b0b03567ea306ef82d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 08:42:22 +0000 Subject: [PATCH 033/313] chore(deps): bump axios from 1.15.0 to 1.15.2 in /frontend Bumps [axios](https://github.com/axios/axios) from 1.15.0 to 1.15.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.15.0...v1.15.2) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 2a5343909..eebf4aeb6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -76,7 +76,7 @@ "@tiptap/vue-3": "3.17.0", "@vueuse/core": "14.1.0", "@vueuse/router": "14.1.0", - "axios": "1.15.0", + "axios": "1.15.2", "blurhash": "2.0.5", "bulma-css-variables": "0.9.33", "change-case": "5.4.4", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 9184dec08..6e3360f9f 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -91,8 +91,8 @@ importers: specifier: 14.1.0 version: 14.1.0(vue-router@4.6.4(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) axios: - specifier: 1.15.0 - version: 1.15.0 + specifier: 1.15.2 + version: 1.15.2 blurhash: specifier: 2.0.5 version: 2.0.5 @@ -3302,8 +3302,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.15.0: - resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} + axios@1.15.2: + resolution: {integrity: sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==} b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -4382,8 +4382,8 @@ packages: resolution: {integrity: sha512-Wn2i1In6XFxl8Az55kkgnFRiAlIAushzh26PTjL2AKtQcEfXrcLa7Hn5QOWGZEf3LU057P9TwwZjFyxfS1VuvQ==} engines: {node: '>=20'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} hast-util-to-html@9.0.5: @@ -10161,7 +10161,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - axios@1.15.0: + axios@1.15.2: dependencies: follow-redirects: 1.16.0 form-data: 4.0.5 @@ -10763,7 +10763,7 @@ snapshots: has-property-descriptors: 1.0.2 has-proto: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.3 internal-slot: 1.1.0 is-array-buffer: 3.0.5 is-callable: 1.2.7 @@ -10813,7 +10813,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 es-to-primitive@1.3.0: dependencies: @@ -11171,7 +11171,7 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.3 mime-types: 2.1.35 fraction.js@5.3.4: {} @@ -11205,7 +11205,7 @@ snapshots: call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 - hasown: 2.0.2 + hasown: 2.0.3 is-callable: 1.2.7 functions-have-names@1.2.3: {} @@ -11230,7 +11230,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.3 math-intrinsics: 1.1.0 get-own-enumerable-property-symbols@3.0.2: {} @@ -11385,7 +11385,7 @@ snapshots: dependencies: hookified: 1.15.1 - hasown@2.0.2: + hasown@2.0.3: dependencies: function-bind: 1.1.2 @@ -11554,7 +11554,7 @@ snapshots: internal-slot@1.1.0: dependencies: es-errors: 1.3.0 - hasown: 2.0.2 + hasown: 2.0.3 side-channel: 1.1.0 ip-address@9.0.5: @@ -11595,7 +11595,7 @@ snapshots: is-core-module@2.15.1: dependencies: - hasown: 2.0.2 + hasown: 2.0.3 is-data-view@1.0.2: dependencies: @@ -11681,7 +11681,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 is-regexp@1.0.0: {} @@ -14110,7 +14110,7 @@ snapshots: wait-on@9.0.5: dependencies: - axios: 1.15.0 + axios: 1.15.2 joi: 18.1.2 lodash: 4.18.1 minimist: 1.2.8 From 7800102f937efa5fbcec6262a1159beb4441caf7 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 6 May 2026 16:07:46 +0200 Subject: [PATCH 034/313] fix(models): allow user-delete cascade to complete for disabled creators TaskAttachment.ReadOne now swallows ErrAccountDisabled/ErrAccountLocked from the creator lookup, matching the existing ErrUserDoesNotExist swallow. Without this, deleting a disabled user that owned a project with task attachments would fail when the cascade re-loaded the attachment to delete it. --- pkg/models/task_attachment.go | 4 ++-- pkg/models/user_delete_test.go | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/pkg/models/task_attachment.go b/pkg/models/task_attachment.go index 23e3fb5c4..59d8d7594 100644 --- a/pkg/models/task_attachment.go +++ b/pkg/models/task_attachment.go @@ -134,9 +134,9 @@ func (ta *TaskAttachment) ReadOne(s *xorm.Session, _ web.Auth) (err error) { return } - // Get the creator (non-fatal if user doesn't exist) + // Swallow missing/disabled/locked so the user-delete cascade can complete. ta.CreatedBy, err = user.GetUserByID(s, ta.CreatedByID) - if err != nil && !user.IsErrUserDoesNotExist(err) { + if err != nil && !user.IsErrUserDoesNotExist(err) && !user.IsErrUserStatusError(err) { return err } diff --git a/pkg/models/user_delete_test.go b/pkg/models/user_delete_test.go index d705616b3..fa24cd928 100644 --- a/pkg/models/user_delete_test.go +++ b/pkg/models/user_delete_test.go @@ -86,6 +86,46 @@ func TestDeleteUser(t *testing.T) { require.NoError(t, s.Commit()) db.AssertMissing(t, "users", map[string]interface{}{"id": u.ID}) }) + t.Run("disabled user with task attachment they created", func(t *testing.T) { + // Regression test: the cascade calls TaskAttachment.Delete -> ReadOne, + // which loads the attachment's creator via user.GetUserByID. If the + // creator is the disabled user being deleted, that lookup must not + // surface ErrAccountDisabled out of the cascade. + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + notifications.Fake() + + project := &Project{ + Title: "disabled user project", + OwnerID: 17, + } + _, err := s.Insert(project) + require.NoError(t, err) + + task := &Task{ + Title: "disabled user task", + ProjectID: project.ID, + CreatedByID: 17, + Index: 1, + } + _, err = s.Insert(task) + require.NoError(t, err) + + _, err = s.Insert(&TaskAttachment{ + TaskID: task.ID, + FileID: 1, + CreatedByID: 17, + }) + require.NoError(t, err) + + err = DeleteUser(s, &user.User{ID: 17}) + require.NoError(t, err) + require.NoError(t, s.Commit()) + db.AssertMissing(t, "users", map[string]interface{}{"id": 17}) + db.AssertMissing(t, "projects", map[string]interface{}{"id": project.ID}) + db.AssertMissing(t, "tasks", map[string]interface{}{"id": task.ID}) + }) t.Run("cleans up task assignments and subscriptions", func(t *testing.T) { db.LoadAndAssertFixtures(t) s := db.NewSession() From beaf4e9e6574774deaf7f7608050474e129c4e9f Mon Sep 17 00:00:00 2001 From: MidoriKurage Date: Wed, 6 May 2026 22:05:36 +0800 Subject: [PATCH 035/313] fix(static): Correct the API_URL value to replace in index.html --- pkg/routes/static.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/routes/static.go b/pkg/routes/static.go index 3f5162829..c16b275ae 100644 --- a/pkg/routes/static.go +++ b/pkg/routes/static.go @@ -118,7 +118,7 @@ func serveIndexFile(c *echo.Context, assetFs http.FileSystem) (err error) { publicURL = "/" } - scriptConfigString = strings.ReplaceAll(scriptConfigString, "'http://localhost:3456/api/v1'", "'"+publicURL+"api/v1'") + scriptConfigString = strings.ReplaceAll(scriptConfigString, "'/api/v1'", "'"+publicURL+"api/v1'") } reader := strings.NewReader(scriptConfigString) From 812fa11b9bcbd5b84aee042375a36019ef28c7ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 05:24:10 +0000 Subject: [PATCH 036/313] chore(deps): update dependency vite to v7.3.3 --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 114 ++++++++++++++++++++-------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index eebf4aeb6..6d49b8042 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -149,7 +149,7 @@ "tailwindcss": "4.2.4", "typescript": "5.9.3", "unplugin-inject-preload": "3.0.0", - "vite": "7.3.2", + "vite": "7.3.3", "vite-plugin-pwa": "1.3.0", "vite-plugin-vue-devtools": "8.1.1", "vite-svg-loader": "5.1.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 6e3360f9f..5433e6189 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -174,10 +174,10 @@ importers: version: 10.4.0 '@histoire/plugin-screenshot': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) '@histoire/plugin-vue': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@playwright/test': specifier: 1.58.2 version: 1.58.2 @@ -186,7 +186,7 @@ importers: version: 3.6.1 '@tailwindcss/vite': specifier: 4.2.4 - version: 4.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + version: 4.2.4(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -213,7 +213,7 @@ importers: version: 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.6 - version: 6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 6.0.6(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) @@ -255,7 +255,7 @@ importers: version: 20.9.0 histoire: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + version: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) otplib: specifier: 12.0.1 version: 12.0.1 @@ -305,20 +305,20 @@ importers: specifier: 3.0.0 version: 3.0.0 vite: - specifier: 7.3.2 - version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + specifier: 7.3.3 + version: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: specifier: 1.3.0 - version: 1.3.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) + version: 1.3.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) vite-plugin-vue-devtools: specifier: 8.1.1 - version: 8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 8.1.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) vite-svg-loader: specifier: 5.1.1 version: 5.1.1(vue@3.5.27(typescript@5.9.3)) vitest: specifier: 4.1.5 - version: 4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + version: 4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: specifier: 3.2.8 version: 3.2.8(typescript@5.9.3) @@ -6707,8 +6707,8 @@ packages: peerDependencies: vue: '>=3.2.13' - vite@7.3.2: - resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + vite@7.3.3: + resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -8597,17 +8597,17 @@ snapshots: dependencies: '@hapi/hoek': 11.0.7 - '@histoire/app@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/app@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 fuse.js: 7.1.0 shiki: 3.2.1 transitivePeerDependencies: - vite - '@histoire/controls@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/controls@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@codemirror/commands': 6.8.1 '@codemirror/lang-json': 6.0.1 @@ -8616,17 +8616,17 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.36.5 - '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 transitivePeerDependencies: - vite - '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': + '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': dependencies: capture-website: 4.2.0(typescript@5.9.3) defu: 6.1.7 fs-extra: 11.2.0 - histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) pathe: 1.1.2 transitivePeerDependencies: - bare-buffer @@ -8635,21 +8635,21 @@ snapshots: - typescript - utf-8-validate - '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 change-case: 5.4.4 globby: 14.1.0 - histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) launch-editor: 2.10.0 pathe: 1.1.2 vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - vite - '@histoire/shared@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/shared@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@histoire/vendors': 1.0.0-beta.1 '@types/fs-extra': 11.0.4 @@ -8657,7 +8657,7 @@ snapshots: chokidar: 4.0.3 pathe: 1.1.2 picocolors: 1.1.1 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@histoire/vendors@1.0.0-beta.1': {} @@ -9275,12 +9275,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - '@tailwindcss/vite@4.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.4(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@tiptap/core@3.17.0(@tiptap/pm@3.17.0)': dependencies: @@ -9811,10 +9811,10 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.13 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vue: 3.5.27(typescript@5.9.3) '@vitest/expect@4.1.5': @@ -9826,13 +9826,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@vitest/mocker@4.1.5(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@vitest/pretty-format@4.1.5': dependencies: @@ -11409,12 +11409,12 @@ snapshots: highlight.js@11.11.1: {} - histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): + histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/app': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 '@types/markdown-it': 14.1.2 birpc: 0.2.19 @@ -11439,7 +11439,7 @@ snapshots: sade: 1.8.1 shiki: 3.2.1 sirv: 3.0.2 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-node: 3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@exodus/crypto' @@ -13891,15 +13891,15 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: birpc: 2.6.1 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-hot-client: 2.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-hot-client@2.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-node@3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: @@ -13907,7 +13907,7 @@ snapshots: debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -13922,7 +13922,7 @@ snapshots: - tsx - yaml - vite-plugin-inspect@11.3.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: ansis: 4.1.0 debug: 4.4.3 @@ -13932,37 +13932,37 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.0 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-dev-rpc: 1.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.3.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): + vite-plugin-pwa@1.3.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) workbox-build: 7.4.1 workbox-window: 7.4.1 transitivePeerDependencies: - supports-color - vite-plugin-vue-devtools@8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): + vite-plugin-vue-devtools@8.1.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): dependencies: '@vue/devtools-core': 8.1.1(vue@3.5.27(typescript@5.9.3)) '@vue/devtools-kit': 8.1.1 '@vue/devtools-shared': 8.1.1 sirv: 3.0.2 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-plugin-inspect: 11.3.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-plugin-vue-inspector: 5.3.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-plugin-inspect: 11.3.3(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite-plugin-vue-inspector: 5.3.2(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - '@nuxt/kit' - supports-color - vue - vite-plugin-vue-inspector@5.3.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-vue-inspector@5.3.2(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -13973,7 +13973,7 @@ snapshots: '@vue/compiler-dom': 3.5.27 kolorist: 1.8.0 magic-string: 0.30.21 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - supports-color @@ -13985,7 +13985,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): + vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) @@ -14003,10 +14003,10 @@ snapshots: terser: 5.31.6 yaml: 2.8.3 - vitest@4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vitest@4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@vitest/mocker': 4.1.5(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.5 '@vitest/runner': 4.1.5 '@vitest/snapshot': 4.1.5 @@ -14023,7 +14023,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.12.2 From c6bda7a2ddc50cee3db0d1a16afe7d470093d877 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Thu, 7 May 2026 21:45:37 +0000 Subject: [PATCH 037/313] feat(oauth2server): accept loopback redirect URIs Previously the OAuth server rejected every redirect_uri that did not start with a vikunja- custom scheme. Native apps that cannot register a custom scheme (e.g. CLIs, desktop tools) need loopback redirects per RFC 8252, so also allow http://localhost, http://127.0.0.1 and http://[::1] (any port). Non-loopback http:// and https:// targets remain rejected. https://claude.ai/code/session_01LsTDrCJ7trE6WQ4FYf78UB --- pkg/modules/auth/oauth2server/client.go | 20 ++++++++++++---- pkg/modules/auth/oauth2server/client_test.go | 25 ++++++++++++++++++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/pkg/modules/auth/oauth2server/client.go b/pkg/modules/auth/oauth2server/client.go index 44e381958..cad975731 100644 --- a/pkg/modules/auth/oauth2server/client.go +++ b/pkg/modules/auth/oauth2server/client.go @@ -21,15 +21,25 @@ import ( "strings" ) -// ValidateRedirectURI checks that the redirect_uri uses a scheme starting with -// "vikunja-". This allowlists only Vikunja native app schemes (e.g. -// vikunja-flutter://callback) and rejects dangerous schemes like javascript:, -// data:, http:, https:, etc. +// ValidateRedirectURI checks that the redirect_uri is either a Vikunja native +// app scheme (e.g. vikunja-flutter://callback) or a loopback http URL as +// recommended by RFC 8252 for native apps that cannot register a custom +// scheme. Dangerous schemes like javascript:, data:, https://, or non-loopback +// http:// targets are rejected. func ValidateRedirectURI(redirectURI string) bool { u, err := url.Parse(redirectURI) if err != nil || u.Scheme == "" { return false } - return strings.HasPrefix(u.Scheme, "vikunja-") + if strings.HasPrefix(u.Scheme, "vikunja-") { + return true + } + + if u.Scheme == "http" { + host := u.Hostname() + return host == "localhost" || host == "127.0.0.1" || host == "::1" + } + + return false } diff --git a/pkg/modules/auth/oauth2server/client_test.go b/pkg/modules/auth/oauth2server/client_test.go index 328e1fb55..40d602595 100644 --- a/pkg/modules/auth/oauth2server/client_test.go +++ b/pkg/modules/auth/oauth2server/client_test.go @@ -29,11 +29,32 @@ func TestValidateRedirectURI(t *testing.T) { t.Run("accepts vikunja-desktop scheme", func(t *testing.T) { assert.True(t, ValidateRedirectURI("vikunja-desktop://auth")) }) + t.Run("accepts http localhost", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://localhost/callback")) + }) + t.Run("accepts http localhost with port", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://localhost:8080/callback")) + }) + t.Run("accepts http 127.0.0.1", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://127.0.0.1:8080/callback")) + }) + t.Run("accepts http ipv6 loopback", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://[::1]:8080/callback")) + }) t.Run("rejects https scheme", func(t *testing.T) { assert.False(t, ValidateRedirectURI("https://evil.com/callback")) }) - t.Run("rejects http scheme", func(t *testing.T) { - assert.False(t, ValidateRedirectURI("http://localhost/callback")) + t.Run("rejects https localhost", func(t *testing.T) { + assert.False(t, ValidateRedirectURI("https://localhost/callback")) + }) + t.Run("rejects non-loopback http", func(t *testing.T) { + assert.False(t, ValidateRedirectURI("http://evil.com/callback")) + }) + t.Run("rejects http with localhost in path", func(t *testing.T) { + assert.False(t, ValidateRedirectURI("http://evil.com/localhost")) + }) + t.Run("rejects http with localhost subdomain trick", func(t *testing.T) { + assert.False(t, ValidateRedirectURI("http://localhost.evil.com/callback")) }) t.Run("rejects javascript scheme", func(t *testing.T) { assert.False(t, ValidateRedirectURI("javascript:alert(1)")) From aa1956e1aabc1a737bc3ead184e91ad063133bff Mon Sep 17 00:00:00 2001 From: Tink bot Date: Thu, 7 May 2026 21:52:18 +0000 Subject: [PATCH 038/313] fix(oauth2server): accept all loopback redirect forms Hardcoding the three exact strings localhost / 127.0.0.1 / ::1 rejected legitimate loopback redirects like 127.0.0.2:1234 (anywhere in 127.0.0.0/8) or [0:0:0:0:0:0:0:1]:1234 (expanded IPv6 loopback). Use net.IP.IsLoopback() to cover the full loopback ranges, and match "localhost" case-insensitively. 0.0.0.0 stays rejected as it is not a loopback address. https://claude.ai/code/session_01LsTDrCJ7trE6WQ4FYf78UB --- pkg/modules/auth/oauth2server/client.go | 14 +++++++++++--- pkg/modules/auth/oauth2server/client_test.go | 12 ++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pkg/modules/auth/oauth2server/client.go b/pkg/modules/auth/oauth2server/client.go index cad975731..1ec866733 100644 --- a/pkg/modules/auth/oauth2server/client.go +++ b/pkg/modules/auth/oauth2server/client.go @@ -17,6 +17,7 @@ package oauth2server import ( + "net" "net/url" "strings" ) @@ -24,8 +25,10 @@ import ( // ValidateRedirectURI checks that the redirect_uri is either a Vikunja native // app scheme (e.g. vikunja-flutter://callback) or a loopback http URL as // recommended by RFC 8252 for native apps that cannot register a custom -// scheme. Dangerous schemes like javascript:, data:, https://, or non-loopback -// http:// targets are rejected. +// scheme. Any address in 127.0.0.0/8, the IPv6 loopback (::1, in any +// notation), and the literal hostname "localhost" are accepted; dangerous +// schemes like javascript:, data:, https://, or non-loopback http:// targets +// are rejected. func ValidateRedirectURI(redirectURI string) bool { u, err := url.Parse(redirectURI) if err != nil || u.Scheme == "" { @@ -38,7 +41,12 @@ func ValidateRedirectURI(redirectURI string) bool { if u.Scheme == "http" { host := u.Hostname() - return host == "localhost" || host == "127.0.0.1" || host == "::1" + if strings.EqualFold(host, "localhost") { + return true + } + if ip := net.ParseIP(host); ip != nil && ip.IsLoopback() { + return true + } } return false diff --git a/pkg/modules/auth/oauth2server/client_test.go b/pkg/modules/auth/oauth2server/client_test.go index 40d602595..c1626f100 100644 --- a/pkg/modules/auth/oauth2server/client_test.go +++ b/pkg/modules/auth/oauth2server/client_test.go @@ -38,9 +38,21 @@ func TestValidateRedirectURI(t *testing.T) { t.Run("accepts http 127.0.0.1", func(t *testing.T) { assert.True(t, ValidateRedirectURI("http://127.0.0.1:8080/callback")) }) + t.Run("accepts other 127.0.0.0/8 loopback addresses", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://127.0.0.2:1234/callback")) + }) t.Run("accepts http ipv6 loopback", func(t *testing.T) { assert.True(t, ValidateRedirectURI("http://[::1]:8080/callback")) }) + t.Run("accepts expanded ipv6 loopback", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://[0:0:0:0:0:0:0:1]:1234/callback")) + }) + t.Run("accepts localhost case-insensitively", func(t *testing.T) { + assert.True(t, ValidateRedirectURI("http://LocalHost:8080/callback")) + }) + t.Run("rejects 0.0.0.0", func(t *testing.T) { + assert.False(t, ValidateRedirectURI("http://0.0.0.0:8080/callback")) + }) t.Run("rejects https scheme", func(t *testing.T) { assert.False(t, ValidateRedirectURI("https://evil.com/callback")) }) From c19b310b2262b45061492700d3460064037d7f3c Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Fri, 8 May 2026 02:05:11 +0000 Subject: [PATCH 039/313] chore(i18n): update translations via Crowdin --- frontend/src/i18n/lang/uk-UA.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/i18n/lang/uk-UA.json b/frontend/src/i18n/lang/uk-UA.json index c47f4007e..87820eb34 100644 --- a/frontend/src/i18n/lang/uk-UA.json +++ b/frontend/src/i18n/lang/uk-UA.json @@ -10,7 +10,7 @@ "welcomeNightQuiet": "Тиха година, {username}", "welcomeNightLate": "Вже пізно, {username}", "welcomeNightMoonlit": "Нічне планування, {username}?", - "welcomeMorning": "Добрий ранок, {username}!", + "welcomeMorning": "Доброго ранку, {username}!", "welcomeMorningHey": "Привіт {username}, можемо починати?", "welcomeMorningFresh": "Новий старт, {username}", "welcomeMorningCoffee": "Кава і завдання, {username}?", From 572edd431dac1f973bf40f61a2c7cece804d13f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 05:39:23 +0000 Subject: [PATCH 040/313] chore(deps): update dev-dependencies --- frontend/package.json | 4 +- frontend/pnpm-lock.yaml | 178 ++++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 6d49b8042..58875cefc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -113,7 +113,7 @@ "@tsconfig/node24": "24.0.4", "@types/codemirror": "5.60.17", "@types/is-touch-device": "1.0.3", - "@types/node": "24.12.2", + "@types/node": "24.12.3", "@types/sortablejs": "1.15.9", "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "8.59.2", @@ -151,7 +151,7 @@ "unplugin-inject-preload": "3.0.0", "vite": "7.3.3", "vite-plugin-pwa": "1.3.0", - "vite-plugin-vue-devtools": "8.1.1", + "vite-plugin-vue-devtools": "8.1.2", "vite-svg-loader": "5.1.1", "vitest": "4.1.5", "vue-tsc": "3.2.8", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 5433e6189..83cbb0146 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -174,10 +174,10 @@ importers: version: 10.4.0 '@histoire/plugin-screenshot': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) '@histoire/plugin-vue': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@playwright/test': specifier: 1.58.2 version: 1.58.2 @@ -186,7 +186,7 @@ importers: version: 3.6.1 '@tailwindcss/vite': specifier: 4.2.4 - version: 4.2.4(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + version: 4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -197,8 +197,8 @@ importers: specifier: 1.0.3 version: 1.0.3 '@types/node': - specifier: 24.12.2 - version: 24.12.2 + specifier: 24.12.3 + version: 24.12.3 '@types/sortablejs': specifier: 1.15.9 version: 1.15.9 @@ -213,7 +213,7 @@ importers: version: 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.6 - version: 6.0.6(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 6.0.6(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) @@ -255,7 +255,7 @@ importers: version: 20.9.0 histoire: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + version: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) otplib: specifier: 12.0.1 version: 12.0.1 @@ -306,19 +306,19 @@ importers: version: 3.0.0 vite: specifier: 7.3.3 - version: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + version: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: specifier: 1.3.0 - version: 1.3.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) + version: 1.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) vite-plugin-vue-devtools: - specifier: 8.1.1 - version: 8.1.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + specifier: 8.1.2 + version: 8.1.2(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) vite-svg-loader: specifier: 5.1.1 version: 5.1.1(vue@3.5.27(typescript@5.9.3)) vitest: specifier: 4.1.5 - version: 4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + version: 4.1.5(@types/node@24.12.3)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: specifier: 3.2.8 version: 3.2.8(typescript@5.9.3) @@ -2812,8 +2812,8 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node@24.12.2': - resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + '@types/node@24.12.3': + resolution: {integrity: sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -3093,22 +3093,22 @@ packages: '@vue/devtools-api@7.7.7': resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} - '@vue/devtools-core@8.1.1': - resolution: {integrity: sha512-bCCsSABp1/ot4j8xJEycM6Mtt2wbuucfByr6hMgjbYhrtlscOJypZKvy8f1FyWLYrLTchB5Qz216Lm92wfbq0A==} + '@vue/devtools-core@8.1.2': + resolution: {integrity: sha512-ZGGyaSBP4/+bN2Nd9ZHNYAVDRIzMw1rv2RyXWtyZlo6mQal+IDmTvKY4V+DjAEBhaXt30mHmsgYp1yXJ/2tIWg==} peerDependencies: vue: ^3.0.0 '@vue/devtools-kit@7.7.7': resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} - '@vue/devtools-kit@8.1.1': - resolution: {integrity: sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==} + '@vue/devtools-kit@8.1.2': + resolution: {integrity: sha512-f75/upc+GCyjXErpgPGz4582ujS0L/adAltGy+tqXMGUJpgAcfGr6CxnnhpZY8BHuMYt6KpbF8uaFrrQG66rGQ==} '@vue/devtools-shared@7.7.7': resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} - '@vue/devtools-shared@8.1.1': - resolution: {integrity: sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==} + '@vue/devtools-shared@8.1.2': + resolution: {integrity: sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==} '@vue/eslint-config-typescript@14.7.0': resolution: {integrity: sha512-iegbMINVc+seZ/QxtzWiOBozctrHiF2WvGedruu2EbLujg9VuU0FQiNcN2z1ycuaoKKpF4m2qzB5HDEMKbxtIg==} @@ -6691,16 +6691,16 @@ packages: '@vite-pwa/assets-generator': optional: true - vite-plugin-vue-devtools@8.1.1: - resolution: {integrity: sha512-9qTpOmZ2vHpvlI9hdVXAQ1Ry4I8GcBArU7aPi0qfIaV7fQIXy0L1nb6X4mFY2Gw0dYshHuLbIl0Ulb572SCjsQ==} + vite-plugin-vue-devtools@8.1.2: + resolution: {integrity: sha512-gt5h1CNryR9Hy0tvhSbqY3j0F7aj0pGxBxWLa1lXSiZVkhdWDf0vbCOZyjh8ivFGE6FDHTGy3zkcZGlMZdVHig==} engines: {node: '>=v14.21.3'} peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - vite-plugin-vue-inspector@5.3.2: - resolution: {integrity: sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==} + vite-plugin-vue-inspector@6.0.0: + resolution: {integrity: sha512-OpyITJLgZNibxlrik1EmRtvXHDjLRxNPsWkGFTERZs2LgMEdG4W0WoFt5GIgp3a3jRou+eJR8U1zOBk/XQgEbw==} peerDependencies: - vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vite-svg-loader@5.1.1: resolution: {integrity: sha512-RPzcXA/EpKJA0585x58DBgs7my2VfeJ+j2j1EoHY4Zh82Y7hV4cR1fElgy2aZi85+QSrcLLoTStQ5uZjD68u+Q==} @@ -8597,17 +8597,17 @@ snapshots: dependencies: '@hapi/hoek': 11.0.7 - '@histoire/app@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/app@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 fuse.js: 7.1.0 shiki: 3.2.1 transitivePeerDependencies: - vite - '@histoire/controls@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/controls@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@codemirror/commands': 6.8.1 '@codemirror/lang-json': 6.0.1 @@ -8616,17 +8616,17 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.36.5 - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 transitivePeerDependencies: - vite - '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': + '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': dependencies: capture-website: 4.2.0(typescript@5.9.3) defu: 6.1.7 fs-extra: 11.2.0 - histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) pathe: 1.1.2 transitivePeerDependencies: - bare-buffer @@ -8635,21 +8635,21 @@ snapshots: - typescript - utf-8-validate - '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 change-case: 5.4.4 globby: 14.1.0 - histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) launch-editor: 2.10.0 pathe: 1.1.2 vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - vite - '@histoire/shared@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/shared@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@histoire/vendors': 1.0.0-beta.1 '@types/fs-extra': 11.0.4 @@ -8657,7 +8657,7 @@ snapshots: chokidar: 4.0.3 pathe: 1.1.2 picocolors: 1.1.1 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@histoire/vendors@1.0.0-beta.1': {} @@ -9275,12 +9275,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - '@tailwindcss/vite@4.2.4(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@tiptap/core@3.17.0(@tiptap/pm@3.17.0)': dependencies: @@ -9510,7 +9510,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 24.12.2 + '@types/node': 24.12.3 '@types/hast@3.0.4': dependencies: @@ -9522,7 +9522,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 '@types/linkify-it@5.0.0': {} @@ -9539,7 +9539,7 @@ snapshots: '@types/minimist@1.2.5': {} - '@types/node@24.12.2': + '@types/node@24.12.3': dependencies: undici-types: 7.16.0 @@ -9563,11 +9563,11 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 optional: true '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': @@ -9811,10 +9811,10 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.13 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vue: 3.5.27(typescript@5.9.3) '@vitest/expect@4.1.5': @@ -9826,13 +9826,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@vitest/mocker@4.1.5(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@vitest/pretty-format@4.1.5': dependencies: @@ -9936,10 +9936,10 @@ snapshots: dependencies: '@vue/devtools-kit': 7.7.7 - '@vue/devtools-core@8.1.1(vue@3.5.27(typescript@5.9.3))': + '@vue/devtools-core@8.1.2(vue@3.5.27(typescript@5.9.3))': dependencies: - '@vue/devtools-kit': 8.1.1 - '@vue/devtools-shared': 8.1.1 + '@vue/devtools-kit': 8.1.2 + '@vue/devtools-shared': 8.1.2 vue: 3.5.27(typescript@5.9.3) '@vue/devtools-kit@7.7.7': @@ -9952,9 +9952,9 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.2 - '@vue/devtools-kit@8.1.1': + '@vue/devtools-kit@8.1.2': dependencies: - '@vue/devtools-shared': 8.1.1 + '@vue/devtools-shared': 8.1.2 birpc: 2.6.1 hookable: 5.5.3 perfect-debounce: 2.0.0 @@ -9963,7 +9963,7 @@ snapshots: dependencies: rfdc: 1.4.1 - '@vue/devtools-shared@8.1.1': {} + '@vue/devtools-shared@8.1.2': {} '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: @@ -11349,7 +11349,7 @@ snapshots: happy-dom@20.9.0: dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 @@ -11409,12 +11409,12 @@ snapshots: highlight.js@11.11.1: {} - histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): + histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/app': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 '@types/markdown-it': 14.1.2 birpc: 0.2.19 @@ -11439,8 +11439,8 @@ snapshots: sade: 1.8.1 shiki: 3.2.1 sirv: 3.0.2 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-node: 3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-node: 3.2.4(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@exodus/crypto' - '@types/node' @@ -13891,23 +13891,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: birpc: 2.6.1 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-hot-client: 2.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-hot-client@2.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-node@3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): + vite-node@3.2.4(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -13922,7 +13922,7 @@ snapshots: - tsx - yaml - vite-plugin-inspect@11.3.3(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: ansis: 4.1.0 debug: 4.4.3 @@ -13932,37 +13932,37 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.0 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-dev-rpc: 1.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.3.0(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): + vite-plugin-pwa@1.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) workbox-build: 7.4.1 workbox-window: 7.4.1 transitivePeerDependencies: - supports-color - vite-plugin-vue-devtools@8.1.1(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): + vite-plugin-vue-devtools@8.1.2(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): dependencies: - '@vue/devtools-core': 8.1.1(vue@3.5.27(typescript@5.9.3)) - '@vue/devtools-kit': 8.1.1 - '@vue/devtools-shared': 8.1.1 + '@vue/devtools-core': 8.1.2(vue@3.5.27(typescript@5.9.3)) + '@vue/devtools-kit': 8.1.2 + '@vue/devtools-shared': 8.1.2 sirv: 3.0.2 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-plugin-inspect: 11.3.3(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-plugin-vue-inspector: 5.3.2(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-plugin-inspect: 11.3.3(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite-plugin-vue-inspector: 6.0.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - '@nuxt/kit' - supports-color - vue - vite-plugin-vue-inspector@5.3.2(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-vue-inspector@6.0.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -13973,7 +13973,7 @@ snapshots: '@vue/compiler-dom': 3.5.27 kolorist: 1.8.0 magic-string: 0.30.21 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - supports-color @@ -13985,7 +13985,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): + vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) @@ -13994,7 +13994,7 @@ snapshots: rollup: 4.60.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 @@ -14003,10 +14003,10 @@ snapshots: terser: 5.31.6 yaml: 2.8.3 - vitest@4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vitest@4.1.5(@types/node@24.12.3)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@vitest/mocker': 4.1.5(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.5 '@vitest/runner': 4.1.5 '@vitest/snapshot': 4.1.5 @@ -14023,10 +14023,10 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.3 happy-dom: 20.9.0 jsdom: 27.4.0 transitivePeerDependencies: From f495a792b2037b075467a87e240062d12a982e9e Mon Sep 17 00:00:00 2001 From: Tink bot Date: Mon, 11 May 2026 12:20:47 +0000 Subject: [PATCH 041/313] feat(frontend): apply quick add magic when creating related tasks Route the create flow through taskStore.createNewTask so titles typed into the related-task input get parsed for labels, priority, assignees, due dates and cross-project targets - matching the main add-task input. Also surface the quick-add-magic hint next to the field. --- .../tasks/partials/RelatedTasks.vue | 17 +++- .../related-tasks-quick-add-magic.spec.ts | 96 +++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 frontend/tests/e2e/task/related-tasks-quick-add-magic.spec.ts diff --git a/frontend/src/components/tasks/partials/RelatedTasks.vue b/frontend/src/components/tasks/partials/RelatedTasks.vue index 95ff3b17d..3f9eef36b 100644 --- a/frontend/src/components/tasks/partials/RelatedTasks.vue +++ b/frontend/src/components/tasks/partials/RelatedTasks.vue @@ -36,7 +36,7 @@
+
component is too much resulting in a // weired positioning of the checkbox. Setting the height here is a workaround until we fix the styling // of the component. diff --git a/frontend/tests/e2e/task/related-tasks-quick-add-magic.spec.ts b/frontend/tests/e2e/task/related-tasks-quick-add-magic.spec.ts new file mode 100644 index 000000000..935b1cf9d --- /dev/null +++ b/frontend/tests/e2e/task/related-tasks-quick-add-magic.spec.ts @@ -0,0 +1,96 @@ +import {test, expect} from '../../support/fixtures' +import {ProjectFactory} from '../../factories/project' +import {TaskFactory} from '../../factories/task' +import {UserFactory} from '../../factories/user' +import {createDefaultViews} from '../project/prepareProjects' +import {login} from '../../support/authenticateUser' + +async function openRelatedTasksForm(page) { + await page.locator('.task-view .action-buttons .button').filter({hasText: 'Add Relation'}).click() + const input = page.locator('.task-relations .multiselect input').first() + await expect(input).toBeVisible() + return input +} + +test.describe('Related tasks quick add magic', () => { + test('Applies a label parsed via *prefix to the new related task', async ({authenticatedPage: page}) => { + const project = (await ProjectFactory.create(1, {id: 1, title: 'Project A'}))[0] + await createDefaultViews(project.id) + const parent = (await TaskFactory.create(1, {id: 1, title: 'Parent task', project_id: project.id}, false))[0] + + await page.goto(`/tasks/${parent.id}`) + const input = await openRelatedTasksForm(page) + await input.fill('Subtask one *Urgent') + await input.press('Enter') + + const relatedTaskLink = page.locator('.task-relations .related-tasks .task a').filter({hasText: 'Subtask one'}) + await expect(relatedTaskLink).toBeVisible({timeout: 10000}) + // Quick add magic strips the *Urgent prefix from the title + await expect(relatedTaskLink).not.toContainText('*Urgent') + + await relatedTaskLink.click() + await expect(page).toHaveURL(/\/tasks\/\d+/) + await expect(page.locator('.task-view .details.labels-list .multiselect .input-wrapper span.tag').filter({hasText: 'Urgent'})) + .toBeVisible({timeout: 10000}) + }) + + test('Applies a priority parsed via !prefix to the new related task', async ({authenticatedPage: page}) => { + const project = (await ProjectFactory.create(1, {id: 1, title: 'Project A'}))[0] + await createDefaultViews(project.id) + const parent = (await TaskFactory.create(1, {id: 1, title: 'Parent task', project_id: project.id}, false))[0] + + await page.goto(`/tasks/${parent.id}`) + const input = await openRelatedTasksForm(page) + await input.fill('Important work !4') + await input.press('Enter') + + const relatedTaskLink = page.locator('.task-relations .related-tasks .task a').filter({hasText: 'Important work'}) + await expect(relatedTaskLink).toBeVisible({timeout: 10000}) + await expect(relatedTaskLink).not.toContainText('!4') + + await relatedTaskLink.click() + // Priority 4 is "Urgent" + await expect(page.locator('.task-view .columns.details select').first()).toHaveValue('4', {timeout: 10000}) + }) + + test('Creates the related task in another project via +project prefix', async ({authenticatedPage: page}) => { + const projectA = (await ProjectFactory.create(1, {id: 1, title: 'Source'}))[0] + await createDefaultViews(projectA.id) + const projectB = (await ProjectFactory.create(1, {id: 2, title: 'TargetProject'}, false))[0] + await createDefaultViews(projectB.id, 5) + const parent = (await TaskFactory.create(1, {id: 1, title: 'Parent task', project_id: projectA.id}, false))[0] + + await page.goto(`/tasks/${parent.id}`) + const input = await openRelatedTasksForm(page) + await input.fill('Cross task +TargetProject') + await input.press('Enter') + + const relatedTaskRow = page.locator('.task-relations .related-tasks .task').filter({hasText: 'Cross task'}) + await expect(relatedTaskRow).toBeVisible({timeout: 10000}) + await expect(relatedTaskRow.locator('a')).not.toContainText('+TargetProject') + // Cross-project marker shows the other project name + await expect(relatedTaskRow.locator('.different-project')).toContainText('TargetProject') + }) + + test('Keeps the title literal when quick add magic is disabled', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({ + quickAddMagicMode: 'disabled', + }), + }))[0] + const project = (await ProjectFactory.create(1, {id: 1, title: 'Project A', owner_id: user.id}))[0] + await createDefaultViews(project.id) + const parent = (await TaskFactory.create(1, {id: 1, title: 'Parent task', project_id: project.id, created_by_id: user.id}, false))[0] + + await login(page, apiContext, user) + await page.goto(`/tasks/${parent.id}`) + + const input = await openRelatedTasksForm(page) + await input.fill('Buy milk *Urgent') + await input.press('Enter') + + // With magic disabled, the prefix stays in the title verbatim + await expect(page.locator('.task-relations .related-tasks .task a').filter({hasText: 'Buy milk *Urgent'})) + .toBeVisible({timeout: 10000}) + }) +}) From 57a0b8fee499e6dcfd3a14a40d78e9bbfa79613a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 20:32:17 +0000 Subject: [PATCH 042/313] chore(deps): update dev-dependencies to v4.3.0 --- frontend/package.json | 4 +- frontend/pnpm-lock.yaml | 152 ++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 58875cefc..482dde9c9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -109,7 +109,7 @@ "@histoire/plugin-vue": "1.0.0-beta.1", "@playwright/test": "1.58.2", "@sentry/vite-plugin": "3.6.1", - "@tailwindcss/vite": "4.2.4", + "@tailwindcss/vite": "4.3.0", "@tsconfig/node24": "24.0.4", "@types/codemirror": "5.60.17", "@types/is-touch-device": "1.0.3", @@ -146,7 +146,7 @@ "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", "stylelint-use-logical": "2.1.3", - "tailwindcss": "4.2.4", + "tailwindcss": "4.3.0", "typescript": "5.9.3", "unplugin-inject-preload": "3.0.0", "vite": "7.3.3", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 83cbb0146..8ec59b699 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -185,8 +185,8 @@ importers: specifier: 3.6.1 version: 3.6.1 '@tailwindcss/vite': - specifier: 4.2.4 - version: 4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + specifier: 4.3.0 + version: 4.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -296,8 +296,8 @@ importers: specifier: 2.1.3 version: 2.1.3(stylelint@17.11.0(typescript@5.9.3)) tailwindcss: - specifier: 4.2.4 - version: 4.2.4 + specifier: 4.3.0 + version: 4.3.0 typescript: specifier: 5.9.3 version: 5.9.3 @@ -2485,65 +2485,65 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@tailwindcss/node@4.2.4': - resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} + '@tailwindcss/node@4.3.0': + resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==} - '@tailwindcss/oxide-android-arm64@4.2.4': - resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==} + '@tailwindcss/oxide-android-arm64@4.3.0': + resolution: {integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==} engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.2.4': - resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==} + '@tailwindcss/oxide-darwin-arm64@4.3.0': + resolution: {integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.2.4': - resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==} + '@tailwindcss/oxide-darwin-x64@4.3.0': + resolution: {integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==} engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.2.4': - resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==} + '@tailwindcss/oxide-freebsd-x64@4.3.0': + resolution: {integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': - resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': + resolution: {integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==} engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': - resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==} + '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': + resolution: {integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': - resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==} + '@tailwindcss/oxide-linux-arm64-musl@4.3.0': + resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': - resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==} + '@tailwindcss/oxide-linux-x64-gnu@4.3.0': + resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.2.4': - resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==} + '@tailwindcss/oxide-linux-x64-musl@4.3.0': + resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.2.4': - resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==} + '@tailwindcss/oxide-wasm32-wasi@4.3.0': + resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -2554,24 +2554,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': - resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==} + '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': + resolution: {integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==} engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': - resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==} + '@tailwindcss/oxide-win32-x64-msvc@4.3.0': + resolution: {integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==} engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.2.4': - resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==} + '@tailwindcss/oxide@4.3.0': + resolution: {integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==} engines: {node: '>= 20'} - '@tailwindcss/vite@4.2.4': - resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==} + '@tailwindcss/vite@4.3.0': + resolution: {integrity: sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 @@ -3880,8 +3880,8 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.20.0: - resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} + enhanced-resolve@5.21.3: + resolution: {integrity: sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -6351,11 +6351,11 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tailwindcss@4.2.4: - resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==} + tailwindcss@4.3.0: + resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} tar-fs@3.1.1: @@ -9214,72 +9214,72 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@tailwindcss/node@4.2.4': + '@tailwindcss/node@4.3.0': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.20.0 + enhanced-resolve: 5.21.3 jiti: 2.6.1 lightningcss: 1.32.0 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.2.4 + tailwindcss: 4.3.0 - '@tailwindcss/oxide-android-arm64@4.2.4': + '@tailwindcss/oxide-android-arm64@4.3.0': optional: true - '@tailwindcss/oxide-darwin-arm64@4.2.4': + '@tailwindcss/oxide-darwin-arm64@4.3.0': optional: true - '@tailwindcss/oxide-darwin-x64@4.2.4': + '@tailwindcss/oxide-darwin-x64@4.3.0': optional: true - '@tailwindcss/oxide-freebsd-x64@4.2.4': + '@tailwindcss/oxide-freebsd-x64@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': + '@tailwindcss/oxide-linux-arm64-musl@4.3.0': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': + '@tailwindcss/oxide-linux-x64-gnu@4.3.0': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.2.4': + '@tailwindcss/oxide-linux-x64-musl@4.3.0': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.2.4': + '@tailwindcss/oxide-wasm32-wasi@4.3.0': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': + '@tailwindcss/oxide-win32-x64-msvc@4.3.0': optional: true - '@tailwindcss/oxide@4.2.4': + '@tailwindcss/oxide@4.3.0': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-x64': 4.2.4 - '@tailwindcss/oxide-freebsd-x64': 4.2.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-x64-musl': 4.2.4 - '@tailwindcss/oxide-wasm32-wasi': 4.2.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 + '@tailwindcss/oxide-android-arm64': 4.3.0 + '@tailwindcss/oxide-darwin-arm64': 4.3.0 + '@tailwindcss/oxide-darwin-x64': 4.3.0 + '@tailwindcss/oxide-freebsd-x64': 4.3.0 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.0 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.0 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.0 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.0 + '@tailwindcss/oxide-linux-x64-musl': 4.3.0 + '@tailwindcss/oxide-wasm32-wasi': 4.3.0 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - '@tailwindcss/vite@4.2.4(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@tailwindcss/vite@4.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@tailwindcss/node': 4.2.4 - '@tailwindcss/oxide': 4.2.4 - tailwindcss: 4.2.4 + '@tailwindcss/node': 4.3.0 + '@tailwindcss/oxide': 4.3.0 + tailwindcss: 4.3.0 vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@tiptap/core@3.17.0(@tiptap/pm@3.17.0)': @@ -10720,10 +10720,10 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.20.0: + enhanced-resolve@5.21.3: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.0 + tapable: 2.3.3 entities@4.5.0: {} @@ -13574,9 +13574,9 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tailwindcss@4.2.4: {} + tailwindcss@4.3.0: {} - tapable@2.3.0: {} + tapable@2.3.3: {} tar-fs@3.1.1: dependencies: From 2ad7efb669e3093ad97e947af6fe6af21edfed3a Mon Sep 17 00:00:00 2001 From: Tink bot Date: Thu, 14 May 2026 07:25:31 +0000 Subject: [PATCH 043/313] fix(kanban): prevent task taps from leaking through the sticky add-task footer on touch devices The sticky bucket footer had no z-index, so the absolutely positioned `.handle` overlays on each task (z-index: 1, used to capture taps on touch devices) stacked above the Add Task button. Tapping the button where a task scrolled behind it would open that task instead of opening the new-task input. --- frontend/src/components/project/views/ProjectKanban.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/project/views/ProjectKanban.vue b/frontend/src/components/project/views/ProjectKanban.vue index 325b3d7c3..1bdbf6ee0 100644 --- a/frontend/src/components/project/views/ProjectKanban.vue +++ b/frontend/src/components/project/views/ProjectKanban.vue @@ -1094,6 +1094,7 @@ $filter-container-height: '1rem - #{$switch-view-height}'; .bucket-footer { position: sticky; inset-block-end: 0; + z-index: 2; block-size: min-content; padding: .5rem; background-color: var(--grey-100); From 7caaa9a16a0629242ebb9119cbefe4153a61e015 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 00:33:16 +0000 Subject: [PATCH 044/313] chore(deps): update dev-dependencies --- desktop/package.json | 2 +- desktop/pnpm-lock.yaml | 10 +- frontend/package.json | 10 +- frontend/pnpm-lock.yaml | 404 +++++++++++++++++++++------------------- 4 files changed, 220 insertions(+), 206 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index e60798ba7..1bc0909fa 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -61,7 +61,7 @@ } }, "devDependencies": { - "electron": "40.9.3", + "electron": "40.10.0", "electron-builder": "26.8.1", "unzipper": "0.12.3" }, diff --git a/desktop/pnpm-lock.yaml b/desktop/pnpm-lock.yaml index 488330fa4..aae2ca03a 100644 --- a/desktop/pnpm-lock.yaml +++ b/desktop/pnpm-lock.yaml @@ -19,8 +19,8 @@ importers: version: 5.2.1 devDependencies: electron: - specifier: 40.9.3 - version: 40.9.3 + specifier: 40.10.0 + version: 40.10.0 electron-builder: specifier: 26.8.1 version: 26.8.1(electron-builder-squirrel-windows@24.13.3) @@ -560,8 +560,8 @@ packages: electron-publish@26.8.1: resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} - electron@40.9.3: - resolution: {integrity: sha512-rDcJOT6BBE689Ada+4jD3rVr05pMv9MZOgT0x/rIMVDF9c4ttx4RTb6lVARTyxZC7uqpirttCtcli1eg1DX5qg==} + electron@40.10.0: + resolution: {integrity: sha512-e7XVcAfyWoFQGS7ZhgxeNn0AijHaqgRCa6uA6TYOrvBWv8smI6JILvMR/8DYBIn07oqvxDLRC90tu/xa2cJCow==} engines: {node: '>= 12.20.55'} hasBin: true @@ -2364,7 +2364,7 @@ snapshots: transitivePeerDependencies: - supports-color - electron@40.9.3: + electron@40.10.0: dependencies: '@electron/get': 2.0.3 '@types/node': 24.10.9 diff --git a/frontend/package.json b/frontend/package.json index 482dde9c9..ba4aa302c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -113,11 +113,11 @@ "@tsconfig/node24": "24.0.4", "@types/codemirror": "5.60.17", "@types/is-touch-device": "1.0.3", - "@types/node": "24.12.3", + "@types/node": "24.12.4", "@types/sortablejs": "1.15.9", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.59.2", - "@typescript-eslint/parser": "8.59.2", + "@typescript-eslint/eslint-plugin": "8.59.3", + "@typescript-eslint/parser": "8.59.3", "@vitejs/plugin-vue": "6.0.6", "@vue/eslint-config-typescript": "14.7.0", "@vue/test-utils": "2.4.10", @@ -153,9 +153,9 @@ "vite-plugin-pwa": "1.3.0", "vite-plugin-vue-devtools": "8.1.2", "vite-svg-loader": "5.1.1", - "vitest": "4.1.5", + "vitest": "4.1.6", "vue-tsc": "3.2.8", - "wait-on": "9.0.5", + "wait-on": "9.0.10", "workbox-cli": "7.4.1", "ws": "8.20.0" }, diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 8ec59b699..4825cfab0 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -174,10 +174,10 @@ importers: version: 10.4.0 '@histoire/plugin-screenshot': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) '@histoire/plugin-vue': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@playwright/test': specifier: 1.58.2 version: 1.58.2 @@ -186,7 +186,7 @@ importers: version: 3.6.1 '@tailwindcss/vite': specifier: 4.3.0 - version: 4.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + version: 4.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -197,8 +197,8 @@ importers: specifier: 1.0.3 version: 1.0.3 '@types/node': - specifier: 24.12.3 - version: 24.12.3 + specifier: 24.12.4 + version: 24.12.4 '@types/sortablejs': specifier: 1.15.9 version: 1.15.9 @@ -206,17 +206,17 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.59.2 - version: 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.3 + version: 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.59.2 - version: 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.3 + version: 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.6 - version: 6.0.6(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 6.0.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': specifier: 2.4.10 version: 2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) @@ -249,13 +249,13 @@ importers: version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: specifier: 10.9.1 - version: 10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + version: 10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: specifier: 20.9.0 version: 20.9.0 histoire: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + version: 1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) otplib: specifier: 12.0.1 version: 12.0.1 @@ -306,25 +306,25 @@ importers: version: 3.0.0 vite: specifier: 7.3.3 - version: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + version: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: specifier: 1.3.0 - version: 1.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) + version: 1.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1) vite-plugin-vue-devtools: specifier: 8.1.2 - version: 8.1.2(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 8.1.2(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) vite-svg-loader: specifier: 5.1.1 version: 5.1.1(vue@3.5.27(typescript@5.9.3)) vitest: - specifier: 4.1.5 - version: 4.1.5(@types/node@24.12.3)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + specifier: 4.1.6 + version: 4.1.6(@types/node@24.12.4)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: specifier: 3.2.8 version: 3.2.8(typescript@5.9.3) wait-on: - specifier: 9.0.5 - version: 9.0.5 + specifier: 9.0.10 + version: 9.0.10 workbox-cli: specifier: 7.4.1 version: 7.4.1 @@ -2812,8 +2812,8 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node@24.12.3': - resolution: {integrity: sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==} + '@types/node@24.12.4': + resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2853,11 +2853,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.59.2': - resolution: {integrity: sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==} + '@typescript-eslint/eslint-plugin@8.59.3': + resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.2 + '@typescript-eslint/parser': ^8.59.3 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -2868,8 +2868,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.59.2': - resolution: {integrity: sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==} + '@typescript-eslint/parser@8.59.3': + resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2887,8 +2887,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.2': - resolution: {integrity: sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==} + '@typescript-eslint/project-service@8.59.3': + resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2901,8 +2901,8 @@ packages: resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.2': - resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} + '@typescript-eslint/scope-manager@8.59.3': + resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.56.0': @@ -2917,14 +2917,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.1': - resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} + '@typescript-eslint/tsconfig-utils@8.59.2': + resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.2': - resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} + '@typescript-eslint/tsconfig-utils@8.59.3': + resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2936,8 +2936,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.59.2': - resolution: {integrity: sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==} + '@typescript-eslint/type-utils@8.59.3': + resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2951,14 +2951,14 @@ packages: resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.1': - resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.2': resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.3': + resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.0': resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2971,8 +2971,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/typescript-estree@8.59.2': - resolution: {integrity: sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==} + '@typescript-eslint/typescript-estree@8.59.3': + resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2991,8 +2991,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.2': - resolution: {integrity: sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==} + '@typescript-eslint/utils@8.59.3': + resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3006,8 +3006,8 @@ packages: resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.2': - resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} + '@typescript-eslint/visitor-keys@8.59.3': + resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -3021,11 +3021,11 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - '@vitest/expect@4.1.5': - resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} + '@vitest/expect@4.1.6': + resolution: {integrity: sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==} - '@vitest/mocker@4.1.5': - resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} + '@vitest/mocker@4.1.6': + resolution: {integrity: sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3035,20 +3035,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.5': - resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} + '@vitest/pretty-format@4.1.6': + resolution: {integrity: sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==} - '@vitest/runner@4.1.5': - resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} + '@vitest/runner@4.1.6': + resolution: {integrity: sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==} - '@vitest/snapshot@4.1.5': - resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} + '@vitest/snapshot@4.1.6': + resolution: {integrity: sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==} - '@vitest/spy@4.1.5': - resolution: {integrity: sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==} + '@vitest/spy@4.1.6': + resolution: {integrity: sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==} - '@vitest/utils@4.1.5': - resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} + '@vitest/utils@4.1.6': + resolution: {integrity: sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==} '@volar/language-core@2.4.28': resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} @@ -3305,6 +3305,9 @@ packages: axios@1.15.2: resolution: {integrity: sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} + b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -4725,8 +4728,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - joi@18.1.2: - resolution: {integrity: sha512-rF5MAmps5esSlhCA+N1b6IYHDw9j/btzGaqfgie522jS02Ju/HXBxamlXVlKEHAxoMKQL77HWI8jlqWsFuekZA==} + joi@18.2.1: + resolution: {integrity: sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==} engines: {node: '>= 20'} js-beautify@1.15.1: @@ -6747,20 +6750,20 @@ packages: yaml: optional: true - vitest@4.1.5: - resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} + vitest@4.1.6: + resolution: {integrity: sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.5 - '@vitest/browser-preview': 4.1.5 - '@vitest/browser-webdriverio': 4.1.5 - '@vitest/coverage-istanbul': 4.1.5 - '@vitest/coverage-v8': 4.1.5 - '@vitest/ui': 4.1.5 + '@vitest/browser-playwright': 4.1.6 + '@vitest/browser-preview': 4.1.6 + '@vitest/browser-webdriverio': 4.1.6 + '@vitest/coverage-istanbul': 4.1.6 + '@vitest/coverage-v8': 4.1.6 + '@vitest/ui': 4.1.6 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -6869,8 +6872,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wait-on@9.0.5: - resolution: {integrity: sha512-qgnbHDfDTRIp73ANEJNRW/7kn8CrDUcvZz18xotJQku/P4saTGkbIzvnMZebPmVvVNUiRq1qWAPyqCH+W4H8KA==} + wait-on@9.0.10: + resolution: {integrity: sha512-rCoJEhvMr0X6alHmwc9abbrA5ZrLZFKpFQVKPNFwl2h7DapXOGdmimIHDtLOWhT4PjhZhxFEtZoQgEXbkDWdZw==} engines: {node: '>=20.0.0'} hasBin: true @@ -8597,17 +8600,17 @@ snapshots: dependencies: '@hapi/hoek': 11.0.7 - '@histoire/app@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/app@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 fuse.js: 7.1.0 shiki: 3.2.1 transitivePeerDependencies: - vite - '@histoire/controls@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/controls@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@codemirror/commands': 6.8.1 '@codemirror/lang-json': 6.0.1 @@ -8616,17 +8619,17 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.36.5 - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 transitivePeerDependencies: - vite - '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': + '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': dependencies: capture-website: 4.2.0(typescript@5.9.3) defu: 6.1.7 fs-extra: 11.2.0 - histoire: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) pathe: 1.1.2 transitivePeerDependencies: - bare-buffer @@ -8635,21 +8638,21 @@ snapshots: - typescript - utf-8-validate - '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 change-case: 5.4.4 globby: 14.1.0 - histoire: 1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) launch-editor: 2.10.0 pathe: 1.1.2 vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - vite - '@histoire/shared@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/shared@1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@histoire/vendors': 1.0.0-beta.1 '@types/fs-extra': 11.0.4 @@ -8657,7 +8660,7 @@ snapshots: chokidar: 4.0.3 pathe: 1.1.2 picocolors: 1.1.1 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@histoire/vendors@1.0.0-beta.1': {} @@ -9275,12 +9278,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - '@tailwindcss/vite@4.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@tailwindcss/vite@4.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.3.0 '@tailwindcss/oxide': 4.3.0 tailwindcss: 4.3.0 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@tiptap/core@3.17.0(@tiptap/pm@3.17.0)': dependencies: @@ -9510,7 +9513,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 24.12.3 + '@types/node': 24.12.4 '@types/hast@3.0.4': dependencies: @@ -9522,7 +9525,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 '@types/linkify-it@5.0.0': {} @@ -9539,7 +9542,7 @@ snapshots: '@types/minimist@1.2.5': {} - '@types/node@24.12.3': + '@types/node@24.12.4': dependencies: undici-types: 7.16.0 @@ -9563,11 +9566,11 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 optional: true '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': @@ -9586,14 +9589,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/type-utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9614,12 +9617,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 @@ -9628,8 +9631,8 @@ snapshots: '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) - '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9637,17 +9640,17 @@ snapshots: '@typescript-eslint/project-service@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) - '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.59.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9663,10 +9666,10 @@ snapshots: '@typescript-eslint/types': 8.58.0 '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/scope-manager@8.59.2': + '@typescript-eslint/scope-manager@8.59.3': dependencies: - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: @@ -9676,11 +9679,11 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -9696,11 +9699,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -9712,10 +9715,10 @@ snapshots: '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/types@8.59.1': {} - '@typescript-eslint/types@8.59.2': {} + '@typescript-eslint/types@8.59.3': {} + '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) @@ -9746,12 +9749,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.59.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/project-service': 8.59.3(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.3 @@ -9783,12 +9786,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/types': 8.59.2 - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9804,57 +9807,57 @@ snapshots: '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.0 - '@typescript-eslint/visitor-keys@8.59.2': + '@typescript-eslint/visitor-keys@8.59.3': dependencies: - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/types': 8.59.3 eslint-visitor-keys: 5.0.0 '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.13 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vue: 3.5.27(typescript@5.9.3) - '@vitest/expect@4.1.5': + '@vitest/expect@4.1.6': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.2 - '@vitest/spy': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/spy': 4.1.6 + '@vitest/utils': 4.1.6 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': + '@vitest/mocker@4.1.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@vitest/spy': 4.1.5 + '@vitest/spy': 4.1.6 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - '@vitest/pretty-format@4.1.5': + '@vitest/pretty-format@4.1.6': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.5': + '@vitest/runner@4.1.6': dependencies: - '@vitest/utils': 4.1.5 + '@vitest/utils': 4.1.6 pathe: 2.0.3 - '@vitest/snapshot@4.1.5': + '@vitest/snapshot@4.1.6': dependencies: - '@vitest/pretty-format': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/pretty-format': 4.1.6 + '@vitest/utils': 4.1.6 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.5': {} + '@vitest/spy@4.1.6': {} - '@vitest/utils@4.1.5': + '@vitest/utils@4.1.6': dependencies: - '@vitest/pretty-format': 4.1.5 + '@vitest/pretty-format': 4.1.6 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -9965,11 +9968,11 @@ snapshots: '@vue/devtools-shared@8.1.2': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-vue: 10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-plugin-vue: 10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) @@ -10169,6 +10172,16 @@ snapshots: transitivePeerDependencies: - debug + axios@1.16.1: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + b4a@1.6.7: {} babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.26.0): @@ -10933,7 +10946,7 @@ snapshots: module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): + eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) eslint: 9.39.4(jiti@2.6.1) @@ -10944,7 +10957,7 @@ snapshots: vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: @@ -11349,7 +11362,7 @@ snapshots: happy-dom@20.9.0: dependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 @@ -11409,12 +11422,12 @@ snapshots: highlight.js@11.11.1: {} - histoire@1.0.0-beta.1(@types/node@24.12.3)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): + histoire@1.0.0-beta.1(@types/node@24.12.4)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/app': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 '@types/markdown-it': 14.1.2 birpc: 0.2.19 @@ -11439,8 +11452,8 @@ snapshots: sade: 1.8.1 shiki: 3.2.1 sirv: 3.0.2 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-node: 3.2.4(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-node: 3.2.4(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@exodus/crypto' - '@types/node' @@ -11760,7 +11773,7 @@ snapshots: jiti@2.6.1: {} - joi@18.1.2: + joi@18.2.1: dependencies: '@hapi/address': 5.1.1 '@hapi/formula': 3.0.2 @@ -13891,23 +13904,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: birpc: 2.6.1 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-hot-client: 2.1.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-hot-client@2.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-node@3.2.4(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): + vite-node@3.2.4(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -13922,7 +13935,7 @@ snapshots: - tsx - yaml - vite-plugin-inspect@11.3.3(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: ansis: 4.1.0 debug: 4.4.3 @@ -13932,37 +13945,37 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.0 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-dev-rpc: 1.1.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.3.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): + vite-plugin-pwa@1.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.1)(workbox-window@7.4.1): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) workbox-build: 7.4.1 workbox-window: 7.4.1 transitivePeerDependencies: - supports-color - vite-plugin-vue-devtools@8.1.2(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): + vite-plugin-vue-devtools@8.1.2(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): dependencies: '@vue/devtools-core': 8.1.2(vue@3.5.27(typescript@5.9.3)) '@vue/devtools-kit': 8.1.2 '@vue/devtools-shared': 8.1.2 sirv: 3.0.2 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-plugin-inspect: 11.3.3(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-plugin-vue-inspector: 6.0.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-plugin-inspect: 11.3.3(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite-plugin-vue-inspector: 6.0.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - '@nuxt/kit' - supports-color - vue - vite-plugin-vue-inspector@6.0.0(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-vue-inspector@6.0.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -13973,7 +13986,7 @@ snapshots: '@vue/compiler-dom': 3.5.27 kolorist: 1.8.0 magic-string: 0.30.21 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - supports-color @@ -13985,7 +13998,7 @@ snapshots: transitivePeerDependencies: - supports-color - vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): + vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) @@ -13994,7 +14007,7 @@ snapshots: rollup: 4.60.3 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 @@ -14003,15 +14016,15 @@ snapshots: terser: 5.31.6 yaml: 2.8.3 - vitest@4.1.5(@types/node@24.12.3)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): + vitest@4.1.6(@types/node@24.12.4)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.5 - '@vitest/runner': 4.1.5 - '@vitest/snapshot': 4.1.5 - '@vitest/spy': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/expect': 4.1.6 + '@vitest/mocker': 4.1.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.6 + '@vitest/runner': 4.1.6 + '@vitest/snapshot': 4.1.6 + '@vitest/spy': 4.1.6 + '@vitest/utils': 4.1.6 es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -14023,10 +14036,10 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@24.12.3)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.12.3 + '@types/node': 24.12.4 happy-dom: 20.9.0 jsdom: 27.4.0 transitivePeerDependencies: @@ -14108,15 +14121,16 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wait-on@9.0.5: + wait-on@9.0.10: dependencies: - axios: 1.15.2 - joi: 18.1.2 + axios: 1.16.1 + joi: 18.2.1 lodash: 4.18.1 minimist: 1.2.8 rxjs: 7.8.2 transitivePeerDependencies: - debug + - supports-color wcwidth@1.0.1: dependencies: From 2b38c2a19693bf514fd5ffcb4babb004cd366161 Mon Sep 17 00:00:00 2001 From: Brett Randall Date: Sat, 9 May 2026 08:09:03 +1000 Subject: [PATCH 045/313] chore: add mise.toml to pin tool versions Consolidates tool versions already declared across the project into a single mise.toml so that `mise install` / `mise exec` activates the correct runtime in one step. Without an explicit project-level pin, mise falls back to the global user config, silently using the wrong version even when .nvmrc is present (legacy files rank below all mise config files). Versions mirror existing project pins: - node 24.13.0 (frontend/.nvmrc) - pnpm 10.28.1 (frontend/package.json#packageManager) - go 1.25.7 (go.mod) --- mise.toml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 mise.toml diff --git a/mise.toml b/mise.toml new file mode 100644 index 000000000..2148b7af6 --- /dev/null +++ b/mise.toml @@ -0,0 +1,4 @@ +[tools] +node = "24.13.0" # keep in sync with frontend/.nvmrc +pnpm = "10.28.1" # keep in sync with frontend/package.json#packageManager +go = "1.25.7" # keep in sync with go.mod From bc7e41c2b02f09e0f2f68116b0a4a07a96f4fc3c Mon Sep 17 00:00:00 2001 From: Brett Randall Date: Sat, 9 May 2026 10:56:30 +1000 Subject: [PATCH 046/313] chore(deps): group node and pnpm updates across mise and version files Add packageRules to keep mise.toml in sync with the files it mirrors when Renovate raises version-bump PRs: - node: groups mise.toml and frontend/.nvmrc (nvm manager) into one PR - pnpm: groups mise.toml and frontend/package.json#packageManager (npm manager) into one PR Without these rules Renovate would open separate PRs for each file, allowing them to drift out of sync. --- renovate.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/renovate.json b/renovate.json index ad9041050..0752b1bf1 100644 --- a/renovate.json +++ b/renovate.json @@ -75,6 +75,26 @@ "extends": [ "schedule:weekly" ] + }, + { + "groupName": "node", + "matchPackageNames": [ + "node" + ], + "matchManagers": [ + "mise", + "nvm" + ] + }, + { + "groupName": "pnpm", + "matchPackageNames": [ + "pnpm" + ], + "matchManagers": [ + "mise", + "npm" + ] } ] } From c371ca719622515238d9ab5f763f1e66700f594e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 10:42:28 +0000 Subject: [PATCH 047/313] chore(deps): update dev-dependencies --- frontend/package.json | 12 +- frontend/pnpm-lock.yaml | 739 +++++++++++++++++++++------------------- 2 files changed, 395 insertions(+), 356 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index ba4aa302c..fc79cda7d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -118,7 +118,7 @@ "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "8.59.3", "@typescript-eslint/parser": "8.59.3", - "@vitejs/plugin-vue": "6.0.6", + "@vitejs/plugin-vue": "6.0.7", "@vue/eslint-config-typescript": "14.7.0", "@vue/test-utils": "2.4.10", "@vue/tsconfig": "0.9.1", @@ -137,11 +137,11 @@ "postcss": "8.5.14", "postcss-easing-gradients": "3.0.1", "postcss-html": "1.8.1", - "postcss-preset-env": "11.2.1", - "rollup": "4.60.3", + "postcss-preset-env": "11.3.0", + "rollup": "4.60.4", "rollup-plugin-visualizer": "6.0.11", "sass-embedded": "1.99.0", - "stylelint": "17.11.0", + "stylelint": "17.11.1", "stylelint-config-property-sort-order-smacss": "10.0.0", "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", @@ -154,10 +154,10 @@ "vite-plugin-vue-devtools": "8.1.2", "vite-svg-loader": "5.1.1", "vitest": "4.1.6", - "vue-tsc": "3.2.8", + "vue-tsc": "3.2.9", "wait-on": "9.0.10", "workbox-cli": "7.4.1", - "ws": "8.20.0" + "ws": "8.20.1" }, "pnpm": { "onlyBuiltDependencies": [ diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 4825cfab0..f681726b6 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: overrides: minimatch: ^10.2.3 - rollup: 4.60.3 + rollup: 4.60.4 basic-ftp: '>=5.2.2' serialize-javascript: ^7.0.5 flatted: ^3.4.1 @@ -32,7 +32,7 @@ importers: version: 3.1.3(@fortawesome/fontawesome-svg-core@7.1.0)(vue@3.5.27(typescript@5.9.3)) '@intlify/unplugin-vue-i18n': specifier: 11.0.3 - version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.3)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) + version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.4)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) '@kyvg/vue3-notification': specifier: 3.4.2 version: 3.4.2(vue@3.5.27(typescript@5.9.3)) @@ -212,8 +212,8 @@ importers: specifier: 8.59.3 version: 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': - specifier: 6.0.6 - version: 6.0.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + specifier: 6.0.7 + version: 6.0.7(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) @@ -269,32 +269,32 @@ importers: specifier: 1.8.1 version: 1.8.1 postcss-preset-env: - specifier: 11.2.1 - version: 11.2.1(postcss@8.5.14) + specifier: 11.3.0 + version: 11.3.0(postcss@8.5.14) rollup: - specifier: 4.60.3 - version: 4.60.3 + specifier: 4.60.4 + version: 4.60.4 rollup-plugin-visualizer: specifier: 6.0.11 - version: 6.0.11(rollup@4.60.3) + version: 6.0.11(rollup@4.60.4) sass-embedded: specifier: 1.99.0 version: 1.99.0 stylelint: - specifier: 17.11.0 - version: 17.11.0(typescript@5.9.3) + specifier: 17.11.1 + version: 17.11.1(typescript@5.9.3) stylelint-config-property-sort-order-smacss: specifier: 10.0.0 - version: 10.0.0(stylelint@17.11.0(typescript@5.9.3)) + version: 10.0.0(stylelint@17.11.1(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: 1.6.1 - version: 1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.11.1(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.14)(stylelint@17.11.1(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 - version: 2.1.3(stylelint@17.11.0(typescript@5.9.3)) + version: 2.1.3(stylelint@17.11.1(typescript@5.9.3)) tailwindcss: specifier: 4.3.0 version: 4.3.0 @@ -320,8 +320,8 @@ importers: specifier: 4.1.6 version: 4.1.6(@types/node@24.12.4)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: - specifier: 3.2.8 - version: 3.2.8(typescript@5.9.3) + specifier: 3.2.9 + version: 3.2.9(typescript@5.9.3) wait-on: specifier: 9.0.10 version: 9.0.10 @@ -329,8 +329,8 @@ importers: specifier: 7.4.1 version: 7.4.1 ws: - specifier: 8.20.0 - version: 8.20.0 + specifier: 8.20.1 + version: 8.20.1 packages: @@ -947,6 +947,13 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-calc@3.2.1': + resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-color-parser@3.1.0': resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} engines: {node: '>=18'} @@ -954,8 +961,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@4.1.0': - resolution: {integrity: sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==} + '@csstools/css-color-parser@4.1.1': + resolution: {integrity: sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -996,8 +1003,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/postcss-alpha-function@2.0.4': - resolution: {integrity: sha512-fti7+GybzvfMrv5TSU6x8rWtXWOth5nLefT5w5AKJ3F3T0bZoxlRqajF0ZUgTtnytfMd4dQ8n5UiaNmsjFA65A==} + '@csstools/postcss-alpha-function@2.0.5': + resolution: {integrity: sha512-i2lNJ6b4GdMoybHlpUM07TIk8KQRXTTe7Qf8LfctQhjDRTIgaodWTQqzWU4fpWO/nxBWNkSloDM22Lw/30NBcg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1008,44 +1015,50 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-function-display-p3-linear@2.0.3': - resolution: {integrity: sha512-u8QNV2TKOxG6cqK4ZrJkpctnxdrwdNTMrkyokmCi+iuLpJegOraA0cqC7HoxF2tHhxjuXc+BxwY/Qd62SwvanQ==} + '@csstools/postcss-color-function-display-p3-linear@2.0.4': + resolution: {integrity: sha512-xrGqSFj9pu6XbJYD4NNCxYK9WFbf0KMfXFaisnJezkIRDZCwefUB2azkU4Zr0dFmLtIb9LlshrSZ0be1/QVthQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-function@5.0.3': - resolution: {integrity: sha512-BiBukIeQ7rPjx9A//9+qgJugBjX6FY9eWiojbnfIJCPulWrl8J07rCgQbFkloTXena+a6Aw5xa25weU+3MA75A==} + '@csstools/postcss-color-function@5.0.4': + resolution: {integrity: sha512-PhUu86ppxKcNHHqrJ43ZL1mYa2uHKGRoY0KPbZA9k8iOaanL3I+1zYqbgVumxj1UgNTDw5BE3BUQ1Dono6bD6g==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-mix-function@4.0.3': - resolution: {integrity: sha512-M8ju3iqHRXtW1/5HYuOmi9WFR5rGGFgqkPh+kXkv/eG56oYK/WYtTeIwJgdcro7lRwjlo4Ut8xqbV3Iovkwfrw==} + '@csstools/postcss-color-mix-function@4.0.4': + resolution: {integrity: sha512-zYS78MHBuih9f9qtPFcSvVXMKg9q/lNPeFJUjyw7+/W1VHRjubvs5MlzuC363UUeahAhrOvYdo2ZZhmlxZbj6w==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3': - resolution: {integrity: sha512-tL46UyFjIjz7mDywoPOe/JgOpvMic0rsTUfdMBB1OHrUcCtE8MQpBILzYl/cAOtinJGu+ZQLuDhqTgTBOoeg3g==} + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.4': + resolution: {integrity: sha512-qlrABMEFPUqbCxX0aOsHcxQZo/8XgMqnEtqqtVUbdizcuTUtJyLdHike7hkoemwDspMSEotdIfRlUY4jhZaD+A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-content-alt-text@3.0.0': - resolution: {integrity: sha512-OHa+4aCcrJtHpPWB3zptScHwpS1TUbeLR4uO0ntIz0Su/zw9SoWkVu+tDMSySSAsNtNSI3kut4fTliFwIsrHxA==} + '@csstools/postcss-container-rule-prelude-list@1.0.1': + resolution: {integrity: sha512-c5qlevVGKHU+zDbVoUGSZl1Mw7Vl1gVRKv6cdIYnaoyM+9Ou23Ian0H5Gr2ZF+lsDWovPK03hOSAbkw6HS8aTg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-contrast-color-function@3.0.3': - resolution: {integrity: sha512-YcohXq+/hfYeobKirg3oXGivDaaTfOPv568bE3jYQCn9ILpFz+RgyJR/kF7ZWh5560TTlTjeCqF4ZmVsj2zwnw==} + '@csstools/postcss-content-alt-text@3.0.1': + resolution: {integrity: sha512-mK5lCgzgV/ZC+LgnFy4rAQVMcXR6HsnX3D1+4Q5gshSQsst5TtcvHbxTdzKy1XTv09sNZHJX8CO4CEQF9zA4ug==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-exponential-functions@3.0.2': - resolution: {integrity: sha512-WDrfdFJXF4M67+wniEGr/5XVzsmn1rt2lL1YAlTfE7x7XDlRstTc5e+HuFoGv6jkiMWTwPsiADJaLwsnGC3UjQ==} + '@csstools/postcss-contrast-color-function@3.0.4': + resolution: {integrity: sha512-EiTZzUICztGqEuYg8AVCUWH9vH2jDzO6RryxMja+PWluZHP6n3/iG6i1leTt5LiDQjDUQlCRbQtMNj7V7S+b4Q==} + engines: {node: '>=20.19.0'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-exponential-functions@3.0.3': + resolution: {integrity: sha512-mB/NoeHLBHh0LZiVSrFdRDA/NxSfmg4tSN9117IJH9bdC2BzSTVgc82h3Gu/sdBXay6kDH2sA7fbkTigMiEi2A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1062,26 +1075,32 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-gamut-mapping@3.0.3': - resolution: {integrity: sha512-3v5ZvcVuynhFh5qCJX2LIJ9Iry8/SvxfOEj6vDngNxbH/3OKTZBFLgK+DgLuIbsP1DLA9LLH3Rn7jmRxXgEDLA==} + '@csstools/postcss-gamut-mapping@3.0.4': + resolution: {integrity: sha512-2dWGsxtxypKU9Ra862F2335W8xegRwl9ohQ6hk808PiQlEahSaFtt5fqsGmKDaSiaFUx+2X8GZxVo970Ajr2vQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-gradients-interpolation-method@6.0.3': - resolution: {integrity: sha512-wrRIaRv1dkq30a8nvYWtSAf41bwCl+sVzLBKGnqeOwk81aSktKN3NattJpkiPyoOtEoFqChisl3WH3Csj/rOsw==} + '@csstools/postcss-gradients-interpolation-method@6.0.4': + resolution: {integrity: sha512-sC/7dqVTtQTniLjPp/NagzeUn4sGinnMTicNBLDzirKq/GNXuJaApBOnvBmgNXjV6XPizfMhNRYCk5stn3q2nQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-hwb-function@5.0.3': - resolution: {integrity: sha512-bHz0uc/PBg2wJEAlGinUf494nMyuXsVKH/fExc2xGkvL6WHOKlxzx/lkn+2AVCQACtWBLVRCBDgDnkYr4RSC9w==} + '@csstools/postcss-hwb-function@5.0.4': + resolution: {integrity: sha512-cl0KPaaeYyAXNHO3pqK8adbpbAGmIU1cT1thyaEkmP8yvbJvmyztkpdGADGqziUUoh4dZQ0IhHxOxnKQ296T+A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-ic-unit@5.0.0': - resolution: {integrity: sha512-/ws5d6c4uKqfM9zIL3ugcGI+3fvZEOOkJHNzAyTAGJIdZ+aSL9BVPNlHGV4QzmL0vqBSCOdU3+rhcMEj3+KzYw==} + '@csstools/postcss-ic-unit@5.0.1': + resolution: {integrity: sha512-jmsVLXPdMBTlaJAhiEijhIR3qL0j75MrlRfhJEs91DF1Wlt2kpJTDsbpXQpYFzn1nPFHZC/WEf+Mw0I/HXkHzQ==} + engines: {node: '>=20.19.0'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-image-function@1.0.0': + resolution: {integrity: sha512-iuQztV6Cfeuc7NczazfickrzEhALOpxUS0yWgGkmRY1zZ0CKjBBFc/7WWSN9qupfpNAzHY7cPNcJCqUhtr+YMw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1098,8 +1117,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-light-dark-function@3.0.0': - resolution: {integrity: sha512-s++V5/hYazeRUCYIn2lsBVzUsxdeC46gtwpgW6lu5U/GlPOS5UTDT14kkEyPgXmFbCvaWLREqV7YTMJq1K3G6w==} + '@csstools/postcss-light-dark-function@3.0.1': + resolution: {integrity: sha512-tD2MMJmZ6XXCHgDythLHcXQDNi5z7KEEWPe7JeB3vPcw+YMuMabpW5ugRqndhIrui+vduhc0Md7f7yGPCmOErg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1134,8 +1153,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-media-minmax@3.0.2': - resolution: {integrity: sha512-+ABxs2ZhJDhy+B9PJg7pgkGq6/d3XPXsWl7+6yZfAk4b2ba6aQ1h2AiTn04XwS6rpMpZEF3tONli/ubfu4y8AQ==} + '@csstools/postcss-media-minmax@3.0.3': + resolution: {integrity: sha512-ch1tNS+1QayiHTGsyc53zv3AzrSd0zigjbkfLxoeuzzJyn32+P3V7em3u5vLVnqLMzBbEZK//GI13EVTIPRdDA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1164,8 +1183,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-oklab-function@5.0.3': - resolution: {integrity: sha512-vTMgJFMwMt9gnPvhKaDnMR7E/h9Nb+rPUv825SY5VUo4PWj+w0OH/N2NqgvjYeubaA3BVckbKDlvADATRpD4Hw==} + '@csstools/postcss-oklab-function@5.0.4': + resolution: {integrity: sha512-vIgrKe5ffW99it5SUIXOBczGLSiTaHBhU6afVr9KPwoZ4uq9H0E3Ehvi+xsUjmvnAyMTxOUSszNo04kEhbvYjQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1176,8 +1195,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-progressive-custom-properties@5.0.0': - resolution: {integrity: sha512-NsJoZ89rxmDrUsITf8QIk5w+lQZQ8Xw5K6cLFG+cfiffsLYHb3zcbOOrHLetGl1WIhjWWQ4Cr8MMrg46Q+oACg==} + '@csstools/postcss-progressive-custom-properties@5.1.0': + resolution: {integrity: sha512-lt/4yHy2GdKcGVpK4OGhBdSIq+z2PXynSusSRggn/T4y7uFurYAhdHqo/aYM+xI37vNb8rJlEKchqKKvVCXROQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1188,14 +1207,14 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-random-function@3.0.2': - resolution: {integrity: sha512-iQ3vfX1LIqRXX7P1/ol45EpJ5CTWdQCAfdpTlHlsRPU4jMQeepmeNjQ0F60bj8RWTS1RkJ318fzzq4mUlyZ7hA==} + '@csstools/postcss-random-function@3.0.3': + resolution: {integrity: sha512-0EScyKxscGonwpi30Hj9DEAr0X8D2eDhOqqayQXE91gIqGli9UT+deLYqoogZLOy5GT+ncqltMqztc/q+0UkhA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-relative-color-syntax@4.0.3': - resolution: {integrity: sha512-SZSImz4KufmLi0dRwYivWXlza+7HF84SRApY8R48SyWgn+f0gDvmCn7D2Ie4CED7qU0JJK+YfCUC1HVlaQ10dg==} + '@csstools/postcss-relative-color-syntax@4.0.4': + resolution: {integrity: sha512-reFFKD9eS602We8621e5cAroKD7hH4104duLNBBhzwawGN7dhbnL1+c/DRHqwyq6eGK35HaKMMiifEZhAztlOA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1206,14 +1225,14 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-sign-functions@2.0.2': - resolution: {integrity: sha512-vOxkkMCMVnyaj7CW03uKR2R/zhJaCrptsXlm31HgI/dqC1lSIGnmu5W7N68x23XwcSgc8fE/fg0jKj4x1XFH4w==} + '@csstools/postcss-sign-functions@2.0.3': + resolution: {integrity: sha512-2BCPwlpeQweTC/8S8oQFYhYD5kxYkiroLf3AUJV2kVoKkSZ+4WM4rSwySXlKrqXL8HfCryAwVrJg7B0jr/RnOw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-stepped-value-functions@5.0.2': - resolution: {integrity: sha512-4PtqkRoBcMSxZG00gcDv+nq7cxVUua+Yd7TmG16qzJjdolyICHkx1RfhNL5mKSnWOLxUnk/IdxAoWN+KU7E/ng==} + '@csstools/postcss-stepped-value-functions@5.0.3': + resolution: {integrity: sha512-nXMFQBz5Pi2LLG02iqm2k+scrqwtqJT9ta/gN8S79oBZ23M0E7O3wDJ20//3z5Q6HU5e+K0n+SmmxN6iWtbm6w==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1236,8 +1255,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-trigonometric-functions@5.0.2': - resolution: {integrity: sha512-hRansZmQk1HH11WGUNlWy8H/DCB9Wy6zDbRcyBfF2UUP+V2fubK+qwmq0q6LIDje5gRzxlKyWhgFYxPy1ohivA==} + '@csstools/postcss-trigonometric-functions@5.0.3': + resolution: {integrity: sha512-p9LTvLj+DFpl5RHbG/X9QGwg7BoMOBsRBZqsUAKKVvCw7MRCsk1P1llTUR/MW5nyZ4IsjFGDtDwTTj1reJjxvg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -2175,8 +2194,8 @@ packages: '@remusao/trie@1.5.0': resolution: {integrity: sha512-UX+3utJKgwCsg6sUozjxd38gNMVRXrY4TNX9VvCdSrlZBS1nZjRPi98ON3QjRAdf6KCguJFyQARRsulTeqQiPg==} - '@rolldown/pluginutils@1.0.0-rc.13': - resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} '@rollup/plugin-babel@6.1.0': resolution: {integrity: sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==} @@ -2184,7 +2203,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0 '@types/babel__core': ^7.1.9 - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: '@types/babel__core': optional: true @@ -2195,7 +2214,7 @@ packages: resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: rollup: optional: true @@ -2204,7 +2223,7 @@ packages: resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: rollup: optional: true @@ -2213,7 +2232,7 @@ packages: resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} engines: {node: '>=20.0.0'} peerDependencies: - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: rollup: optional: true @@ -2222,133 +2241,133 @@ packages: resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.3': - resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} + '@rollup/rollup-android-arm-eabi@4.60.4': + resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.3': - resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==} + '@rollup/rollup-android-arm64@4.60.4': + resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.3': - resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==} + '@rollup/rollup-darwin-arm64@4.60.4': + resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.3': - resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==} + '@rollup/rollup-darwin-x64@4.60.4': + resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.3': - resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==} + '@rollup/rollup-freebsd-arm64@4.60.4': + resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.3': - resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==} + '@rollup/rollup-freebsd-x64@4.60.4': + resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': - resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.60.3': - resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==} + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.60.3': - resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} + '@rollup/rollup-linux-arm64-gnu@4.60.4': + resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.60.3': - resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==} + '@rollup/rollup-linux-arm64-musl@4.60.4': + resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.60.3': - resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==} + '@rollup/rollup-linux-loong64-gnu@4.60.4': + resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-musl@4.60.3': - resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==} + '@rollup/rollup-linux-loong64-musl@4.60.4': + resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.60.3': - resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==} + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-musl@4.60.3': - resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==} + '@rollup/rollup-linux-ppc64-musl@4.60.4': + resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.60.3': - resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==} + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.60.3': - resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==} + '@rollup/rollup-linux-riscv64-musl@4.60.4': + resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.60.3': - resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==} + '@rollup/rollup-linux-s390x-gnu@4.60.4': + resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.60.3': - resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==} + '@rollup/rollup-linux-x64-gnu@4.60.4': + resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.60.3': - resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==} + '@rollup/rollup-linux-x64-musl@4.60.4': + resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.60.3': - resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==} + '@rollup/rollup-openbsd-x64@4.60.4': + resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.3': - resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==} + '@rollup/rollup-openharmony-arm64@4.60.4': + resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.3': - resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==} + '@rollup/rollup-win32-arm64-msvc@4.60.4': + resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.3': - resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==} + '@rollup/rollup-win32-ia32-msvc@4.60.4': + resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.3': - resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==} + '@rollup/rollup-win32-x64-gnu@4.60.4': + resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.3': - resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==} + '@rollup/rollup-win32-x64-msvc@4.60.4': + resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} cpu: [x64] os: [win32] @@ -3014,8 +3033,8 @@ packages: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} deprecated: Potential CWE-502 - Update to 1.3.1 or higher - '@vitejs/plugin-vue@6.0.6': - resolution: {integrity: sha512-u9HHgfrq3AjXlysn0eINFnWQOJQLO9WN6VprZ8FXl7A2bYisv3Hui9Ij+7QZ41F/WYWarHjwBbXtD7dKg3uxbg==} + '@vitejs/plugin-vue@6.0.7': + resolution: {integrity: sha512-km+p+XdSz9Sxm5rqUbqcSfZYaAniKxWBj1KURl+Jr7UaPvvX7BmaWMdP69I5rrFDeQGyxAG7NXdc57vz+snhWg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3121,8 +3140,8 @@ packages: typescript: optional: true - '@vue/language-core@3.2.8': - resolution: {integrity: sha512-9OiSPQFiAAWNVnXb0d2dcTmcKnFQamhuNES6ayyISrb/mwPWVgoGdAqSfCWqKhQpa3D5gDTcYD+w7ObiheZ81g==} + '@vue/language-core@3.2.9': + resolution: {integrity: sha512-ie0ojt/0fU/GfIogh+zgHbaYRPlt9S+cLOxcWwF7nTSFh897BVgnFKL2byT4kpp1mlqYWZ2psGwSniyE2xsxYw==} '@vue/reactivity@3.5.27': resolution: {integrity: sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==} @@ -3214,8 +3233,8 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - alien-signals@3.1.2: - resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} + alien-signals@3.2.1: + resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -3660,8 +3679,8 @@ packages: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} - cssdb@8.8.0: - resolution: {integrity: sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q==} + cssdb@8.9.0: + resolution: {integrity: sha512-J8jOU/hLjaXcO1LldOLraJSQpfLXRKof0I7mtbRyOy2AAXgqst0x9rlgi2qXeD6d0ou3ZLqcPAMqYVbpCbrxEw==} cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} @@ -5373,8 +5392,8 @@ packages: peerDependencies: postcss: ^8.4.6 - postcss-color-functional-notation@8.0.3: - resolution: {integrity: sha512-MyaFK+3PusD7F2+qlMDP6+zfSgHWP17AtmvHQs44W3+Qbb39VptVDVRJ4Lf7gHSVffW5ekEy/XrsZ0S0t34hrA==} + postcss-color-functional-notation@8.0.4: + resolution: {integrity: sha512-Zn3yPgBFakVXthmA2n1NUMY7gdhuFUB/DrUJ0Eug/d0rl9wahMQZykp4NVTJLGzQrDUwZ2rzjiTeW5udxFNG8A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5415,8 +5434,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-double-position-gradients@7.0.0: - resolution: {integrity: sha512-Msr/dxj8Os7KLJE5Hdhvprwm3K5Zrh1KTY0eFN3ngPKNkej/Usy4BM9JQmqE6CLAkDpHoQVsi4snbL72CPt6qg==} + postcss-double-position-gradients@7.0.1: + resolution: {integrity: sha512-M69I4EolEGwiYa0KmxKWg4zZp2DxhlNM0Bz12OvHCj930GXDVCvFhdWNGsRscz6BIijN6tFryzSFsy8kMLyD5Q==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5458,8 +5477,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-lab-function@8.0.3: - resolution: {integrity: sha512-rUa27RLVXjMn1aDkHEt5dRsK80+bAACPr8w5Ow0BkIlfH6gEk0Mh1I0REkYhtp4UhKFw1HLEk3AzvKBi6BGOqw==} + postcss-lab-function@8.0.4: + resolution: {integrity: sha512-dqcJSzVasdELD9xqJ1wfP95uzP57J6zFd80c7S3AWK127H9zwqR9Kbk5ZgyIfN2DiMStI7Vq8E7ablXNeTvpew==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5502,8 +5521,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-preset-env@11.2.1: - resolution: {integrity: sha512-dqL7WR5wg9yP/+6pTHIsIeIpK6XVghJDE4/r4ZSdr5ExrbLiN5x78gly0Xs0MLGbHy2oT3WWNfbxowmnw9BurQ==} + postcss-preset-env@11.3.0: + resolution: {integrity: sha512-PpijTuY+NT35vvk7us0pw9lJVrsZZWukjONZsza2Kq1Gag8nrUXRkgdKdxyyhZPJ6R43L3/nLpspUK99TmU9xg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5809,15 +5828,15 @@ packages: hasBin: true peerDependencies: rolldown: 1.x || ^1.0.0-beta - rollup: 4.60.3 + rollup: 4.60.4 peerDependenciesMeta: rolldown: optional: true rollup: optional: true - rollup@4.60.3: - resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} + rollup@4.60.4: + resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -6302,8 +6321,8 @@ packages: peerDependencies: stylelint: '>= 11 < 18' - stylelint@17.11.0: - resolution: {integrity: sha512-/3czzmbF9XdGWvReDF3Ex4R23Ajolo7j8RB2bFNEqk6Ht356nlpVV+G5bG2Qt8AW1ofJzXztBRDnAtd7cgowWA==} + stylelint@17.11.1: + resolution: {integrity: sha512-+smN/HqVTggUx3iuAzOi9fPh8SrH+cJWlZrYVldXoJ06orWBhZ4Ue/QEp64oei6pVrAh4w3tG+Y12Vw7MbCFRQ==} engines: {node: '>=20.19.0'} hasBin: true @@ -6842,8 +6861,8 @@ packages: peerDependencies: vue: ^3.5.0 - vue-tsc@3.2.8: - resolution: {integrity: sha512-27vTLJ6Q2370obOd0PFYoYoKnmXJ521uUIedrs3Zhhhg/8YG10VOCMmwt+JQslatpAMTDbnWiitLnoD5VlIvog==} + vue-tsc@3.2.9: + resolution: {integrity: sha512-qm8/nbo+9eZc1SCndm9wT+gq23pM+wRIdHY0wjm83B3lIginHTwcdrLUyTrKjDWXbMVNjKegNrnymhpdqnCL3A==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -7032,8 +7051,8 @@ packages: resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} engines: {node: ^20.17.0 || >=22.9.0} - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -7919,6 +7938,11 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: '@csstools/color-helpers': 5.1.0 @@ -7926,10 +7950,10 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/color-helpers': 6.0.2 - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -7954,12 +7978,12 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.14)': + '@csstools/postcss-alpha-function@2.0.5(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -7969,62 +7993,68 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.14)': + '@csstools/postcss-color-function-display-p3-linear@2.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-color-function@5.0.3(postcss@8.5.14)': + '@csstools/postcss-color-function@5.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.14)': + '@csstools/postcss-color-mix-function@4.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.14)': + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.14)': + '@csstools/postcss-container-rule-prelude-list@1.0.1(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) - '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.14)': + '@csstools/postcss-content-alt-text@3.0.1(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.14)': + '@csstools/postcss-contrast-color-function@3.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 + + '@csstools/postcss-exponential-functions@3.0.3(postcss@8.5.14)': + dependencies: + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 @@ -8040,38 +8070,46 @@ snapshots: '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.14)': + '@csstools/postcss-gamut-mapping@3.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 - '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.14)': + '@csstools/postcss-gradients-interpolation-method@6.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.14)': + '@csstools/postcss-hwb-function@5.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.14)': + '@csstools/postcss-ic-unit@5.0.1(postcss@8.5.14)': dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 postcss-value-parser: 4.2.0 + '@csstools/postcss-image-function@1.0.0(postcss@8.5.14)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) + '@csstools/utilities': 3.0.0(postcss@8.5.14) + postcss: 8.5.14 + '@csstools/postcss-initial@3.0.0(postcss@8.5.14)': dependencies: postcss: 8.5.14 @@ -8082,11 +8120,11 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.14)': + '@csstools/postcss-light-dark-function@3.0.1(postcss@8.5.14)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -8113,9 +8151,9 @@ snapshots: '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 - '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.14)': + '@csstools/postcss-media-minmax@3.0.3(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) @@ -8145,12 +8183,12 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.14)': + '@csstools/postcss-oklab-function@5.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -8158,7 +8196,7 @@ snapshots: dependencies: postcss: 8.5.14 - '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.14)': + '@csstools/postcss-progressive-custom-properties@5.1.0(postcss@8.5.14)': dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 @@ -8169,19 +8207,19 @@ snapshots: '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 - '@csstools/postcss-random-function@3.0.2(postcss@8.5.14)': + '@csstools/postcss-random-function@3.0.3(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 - '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.14)': + '@csstools/postcss-relative-color-syntax@4.0.4(postcss@8.5.14)': dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -8190,16 +8228,16 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 7.1.1 - '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.14)': + '@csstools/postcss-sign-functions@2.0.3(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 - '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.14)': + '@csstools/postcss-stepped-value-functions@5.0.3(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 @@ -8221,9 +8259,9 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.14)': + '@csstools/postcss-trigonometric-functions@5.0.3(postcss@8.5.14)': dependencies: - '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.14 @@ -8703,13 +8741,13 @@ snapshots: '@intlify/shared@11.2.8': {} - '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.3)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': + '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.4)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@intlify/bundle-utils': 11.0.3(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3))) '@intlify/shared': 11.2.8 '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.8)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) - '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + '@rollup/pluginutils': 5.1.3(rollup@4.60.4) '@typescript-eslint/scope-manager': 8.58.0 '@typescript-eslint/typescript-estree': 8.58.0(typescript@5.9.3) debug: 4.4.3 @@ -8954,124 +8992,124 @@ snapshots: '@remusao/trie@1.5.0': {} - '@rolldown/pluginutils@1.0.0-rc.13': {} + '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-babel@6.1.0(@babel/core@7.26.0)(rollup@4.60.3)': + '@rollup/plugin-babel@6.1.0(@babel/core@7.26.0)(rollup@4.60.4)': dependencies: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 - '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + '@rollup/pluginutils': 5.1.3(rollup@4.60.4) optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.3)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + '@rollup/pluginutils': 5.1.3(rollup@4.60.4) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 - '@rollup/plugin-replace@6.0.3(rollup@4.60.3)': + '@rollup/plugin-replace@6.0.3(rollup@4.60.4)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.60.3) + '@rollup/pluginutils': 5.1.3(rollup@4.60.4) magic-string: 0.30.21 optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 - '@rollup/plugin-terser@1.0.0(rollup@4.60.3)': + '@rollup/plugin-terser@1.0.0(rollup@4.60.4)': dependencies: serialize-javascript: 7.0.5 smob: 1.5.0 terser: 5.31.6 optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 - '@rollup/pluginutils@5.1.3(rollup@4.60.3)': + '@rollup/pluginutils@5.1.3(rollup@4.60.4)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 - '@rollup/rollup-android-arm-eabi@4.60.3': + '@rollup/rollup-android-arm-eabi@4.60.4': optional: true - '@rollup/rollup-android-arm64@4.60.3': + '@rollup/rollup-android-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-arm64@4.60.3': + '@rollup/rollup-darwin-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-x64@4.60.3': + '@rollup/rollup-darwin-x64@4.60.4': optional: true - '@rollup/rollup-freebsd-arm64@4.60.3': + '@rollup/rollup-freebsd-arm64@4.60.4': optional: true - '@rollup/rollup-freebsd-x64@4.60.3': + '@rollup/rollup-freebsd-x64@4.60.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.3': + '@rollup/rollup-linux-arm-musleabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.3': + '@rollup/rollup-linux-arm64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.3': + '@rollup/rollup-linux-arm64-musl@4.60.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.3': + '@rollup/rollup-linux-loong64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.3': + '@rollup/rollup-linux-loong64-musl@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.3': + '@rollup/rollup-linux-ppc64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.3': + '@rollup/rollup-linux-ppc64-musl@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.3': + '@rollup/rollup-linux-riscv64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.3': + '@rollup/rollup-linux-riscv64-musl@4.60.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.3': + '@rollup/rollup-linux-s390x-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.3': + '@rollup/rollup-linux-x64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-musl@4.60.3': + '@rollup/rollup-linux-x64-musl@4.60.4': optional: true - '@rollup/rollup-openbsd-x64@4.60.3': + '@rollup/rollup-openbsd-x64@4.60.4': optional: true - '@rollup/rollup-openharmony-arm64@4.60.3': + '@rollup/rollup-openharmony-arm64@4.60.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.3': + '@rollup/rollup-win32-arm64-msvc@4.60.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.3': + '@rollup/rollup-win32-ia32-msvc@4.60.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.3': + '@rollup/rollup-win32-x64-gnu@4.60.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.3': + '@rollup/rollup-win32-x64-msvc@4.60.4': optional: true '@sentry-internal/browser-utils@10.36.0': @@ -9814,9 +9852,9 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.6(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.7(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@rolldown/pluginutils': 1.0.0-rc.13 + '@rolldown/pluginutils': 1.0.1 vite: 7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vue: 3.5.27(typescript@5.9.3) @@ -9981,12 +10019,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@vue/language-core@3.2.8': + '@vue/language-core@3.2.9': dependencies: '@volar/language-core': 2.4.28 '@vue/compiler-dom': 3.5.27 '@vue/shared': 3.5.27 - alien-signals: 3.1.2 + alien-signals: 3.2.1 muggle-string: 0.4.1 path-browserify: 1.0.1 picomatch: 4.0.4 @@ -10082,7 +10120,7 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - alien-signals@3.1.2: {} + alien-signals@3.2.1: {} ansi-align@3.0.1: dependencies: @@ -10539,7 +10577,7 @@ snapshots: css-what@6.1.0: {} - cssdb@8.8.0: {} + cssdb@8.9.0: {} cssesc@3.0.0: {} @@ -11367,7 +11405,7 @@ snapshots: '@types/ws': 8.18.1 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.20.0 + ws: 8.20.1 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -11828,7 +11866,7 @@ snapshots: webidl-conversions: 8.0.1 whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 - ws: 8.20.0 + ws: 8.20.1 xml-name-validator: 5.0.0 transitivePeerDependencies: - '@exodus/crypto' @@ -12386,12 +12424,12 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@8.0.3(postcss@8.5.14): + postcss-color-functional-notation@8.0.4(postcss@8.5.14): dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -12437,9 +12475,9 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-double-position-gradients@7.0.0(postcss@8.5.14): + postcss-double-position-gradients@7.0.1(postcss@8.5.14): dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 postcss-value-parser: 4.2.0 @@ -12482,12 +12520,12 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-lab-function@8.0.3(postcss@8.5.14): + postcss-lab-function@8.0.4(postcss@8.5.14): dependencies: - '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/utilities': 3.0.0(postcss@8.5.14) postcss: 8.5.14 @@ -12523,73 +12561,75 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-preset-env@11.2.1(postcss@8.5.14): + postcss-preset-env@11.3.0(postcss@8.5.14): dependencies: - '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.14) + '@csstools/postcss-alpha-function': 2.0.5(postcss@8.5.14) '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.14) - '@csstools/postcss-color-function': 5.0.3(postcss@8.5.14) - '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.14) - '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.14) - '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.14) - '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.14) - '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.14) - '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.14) + '@csstools/postcss-color-function': 5.0.4(postcss@8.5.14) + '@csstools/postcss-color-function-display-p3-linear': 2.0.4(postcss@8.5.14) + '@csstools/postcss-color-mix-function': 4.0.4(postcss@8.5.14) + '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.4(postcss@8.5.14) + '@csstools/postcss-container-rule-prelude-list': 1.0.1(postcss@8.5.14) + '@csstools/postcss-content-alt-text': 3.0.1(postcss@8.5.14) + '@csstools/postcss-contrast-color-function': 3.0.4(postcss@8.5.14) + '@csstools/postcss-exponential-functions': 3.0.3(postcss@8.5.14) '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.14) '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.14) - '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.14) - '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.14) - '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.14) - '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.14) + '@csstools/postcss-gamut-mapping': 3.0.4(postcss@8.5.14) + '@csstools/postcss-gradients-interpolation-method': 6.0.4(postcss@8.5.14) + '@csstools/postcss-hwb-function': 5.0.4(postcss@8.5.14) + '@csstools/postcss-ic-unit': 5.0.1(postcss@8.5.14) + '@csstools/postcss-image-function': 1.0.0(postcss@8.5.14) '@csstools/postcss-initial': 3.0.0(postcss@8.5.14) '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.14) - '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.14) + '@csstools/postcss-light-dark-function': 3.0.1(postcss@8.5.14) '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.14) '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.14) '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.14) '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.14) '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.14) - '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.14) + '@csstools/postcss-media-minmax': 3.0.3(postcss@8.5.14) '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.14) '@csstools/postcss-mixins': 1.0.0(postcss@8.5.14) '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.14) '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.14) - '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.14) + '@csstools/postcss-oklab-function': 5.0.4(postcss@8.5.14) '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.14) - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.14) + '@csstools/postcss-progressive-custom-properties': 5.1.0(postcss@8.5.14) '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.14) - '@csstools/postcss-random-function': 3.0.2(postcss@8.5.14) - '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.14) + '@csstools/postcss-random-function': 3.0.3(postcss@8.5.14) + '@csstools/postcss-relative-color-syntax': 4.0.4(postcss@8.5.14) '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.14) - '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.14) - '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.14) + '@csstools/postcss-sign-functions': 2.0.3(postcss@8.5.14) + '@csstools/postcss-stepped-value-functions': 5.0.3(postcss@8.5.14) '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.14) '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.14) '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.14) - '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.14) + '@csstools/postcss-trigonometric-functions': 5.0.3(postcss@8.5.14) '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.14) autoprefixer: 10.5.0(postcss@8.5.14) browserslist: 4.28.2 css-blank-pseudo: 8.0.1(postcss@8.5.14) css-has-pseudo: 8.0.0(postcss@8.5.14) css-prefers-color-scheme: 11.0.0(postcss@8.5.14) - cssdb: 8.8.0 + cssdb: 8.9.0 postcss: 8.5.14 postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.14) postcss-clamp: 4.1.0(postcss@8.5.14) - postcss-color-functional-notation: 8.0.3(postcss@8.5.14) + postcss-color-functional-notation: 8.0.4(postcss@8.5.14) postcss-color-hex-alpha: 11.0.0(postcss@8.5.14) postcss-color-rebeccapurple: 11.0.0(postcss@8.5.14) postcss-custom-media: 12.0.1(postcss@8.5.14) postcss-custom-properties: 15.0.1(postcss@8.5.14) postcss-custom-selectors: 9.0.1(postcss@8.5.14) postcss-dir-pseudo-class: 10.0.0(postcss@8.5.14) - postcss-double-position-gradients: 7.0.0(postcss@8.5.14) + postcss-double-position-gradients: 7.0.1(postcss@8.5.14) postcss-focus-visible: 11.0.0(postcss@8.5.14) postcss-focus-within: 10.0.0(postcss@8.5.14) postcss-font-variant: 5.0.0(postcss@8.5.14) postcss-gap-properties: 7.0.0(postcss@8.5.14) postcss-image-set-function: 8.0.0(postcss@8.5.14) - postcss-lab-function: 8.0.3(postcss@8.5.14) + postcss-lab-function: 8.0.4(postcss@8.5.14) postcss-logical: 9.0.0(postcss@8.5.14) postcss-nesting: 14.0.0(postcss@8.5.14) postcss-opacity-percentage: 3.0.0(postcss@8.5.14) @@ -12804,7 +12844,7 @@ snapshots: debug: 4.4.3 devtools-protocol: 0.0.1367902 typed-query-selector: 2.12.0 - ws: 8.20.0 + ws: 8.20.1 transitivePeerDependencies: - bare-buffer - bufferutil @@ -12959,44 +12999,44 @@ snapshots: rfdc@1.4.1: {} - rollup-plugin-visualizer@6.0.11(rollup@4.60.3): + rollup-plugin-visualizer@6.0.11(rollup@4.60.4): dependencies: open: 8.4.2 picomatch: 4.0.4 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.60.3 + rollup: 4.60.4 - rollup@4.60.3: + rollup@4.60.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.3 - '@rollup/rollup-android-arm64': 4.60.3 - '@rollup/rollup-darwin-arm64': 4.60.3 - '@rollup/rollup-darwin-x64': 4.60.3 - '@rollup/rollup-freebsd-arm64': 4.60.3 - '@rollup/rollup-freebsd-x64': 4.60.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.3 - '@rollup/rollup-linux-arm-musleabihf': 4.60.3 - '@rollup/rollup-linux-arm64-gnu': 4.60.3 - '@rollup/rollup-linux-arm64-musl': 4.60.3 - '@rollup/rollup-linux-loong64-gnu': 4.60.3 - '@rollup/rollup-linux-loong64-musl': 4.60.3 - '@rollup/rollup-linux-ppc64-gnu': 4.60.3 - '@rollup/rollup-linux-ppc64-musl': 4.60.3 - '@rollup/rollup-linux-riscv64-gnu': 4.60.3 - '@rollup/rollup-linux-riscv64-musl': 4.60.3 - '@rollup/rollup-linux-s390x-gnu': 4.60.3 - '@rollup/rollup-linux-x64-gnu': 4.60.3 - '@rollup/rollup-linux-x64-musl': 4.60.3 - '@rollup/rollup-openbsd-x64': 4.60.3 - '@rollup/rollup-openharmony-arm64': 4.60.3 - '@rollup/rollup-win32-arm64-msvc': 4.60.3 - '@rollup/rollup-win32-ia32-msvc': 4.60.3 - '@rollup/rollup-win32-x64-gnu': 4.60.3 - '@rollup/rollup-win32-x64-msvc': 4.60.3 + '@rollup/rollup-android-arm-eabi': 4.60.4 + '@rollup/rollup-android-arm64': 4.60.4 + '@rollup/rollup-darwin-arm64': 4.60.4 + '@rollup/rollup-darwin-x64': 4.60.4 + '@rollup/rollup-freebsd-arm64': 4.60.4 + '@rollup/rollup-freebsd-x64': 4.60.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 + '@rollup/rollup-linux-arm-musleabihf': 4.60.4 + '@rollup/rollup-linux-arm64-gnu': 4.60.4 + '@rollup/rollup-linux-arm64-musl': 4.60.4 + '@rollup/rollup-linux-loong64-gnu': 4.60.4 + '@rollup/rollup-linux-loong64-musl': 4.60.4 + '@rollup/rollup-linux-ppc64-gnu': 4.60.4 + '@rollup/rollup-linux-ppc64-musl': 4.60.4 + '@rollup/rollup-linux-riscv64-gnu': 4.60.4 + '@rollup/rollup-linux-riscv64-musl': 4.60.4 + '@rollup/rollup-linux-s390x-gnu': 4.60.4 + '@rollup/rollup-linux-x64-gnu': 4.60.4 + '@rollup/rollup-linux-x64-musl': 4.60.4 + '@rollup/rollup-openbsd-x64': 4.60.4 + '@rollup/rollup-openharmony-arm64': 4.60.4 + '@rollup/rollup-win32-arm64-msvc': 4.60.4 + '@rollup/rollup-win32-ia32-msvc': 4.60.4 + '@rollup/rollup-win32-x64-gnu': 4.60.4 + '@rollup/rollup-win32-x64-msvc': 4.60.4 fsevents: 2.3.3 rope-sequence@1.3.4: {} @@ -13429,58 +13469,58 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.11.1(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.1(typescript@5.9.3) - stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.11.1(typescript@5.9.3)): dependencies: css-property-sort-order-smacss: 2.2.0 - stylelint: 17.11.0(typescript@5.9.3) - stylelint-order: 6.0.4(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.1(typescript@5.9.3) + stylelint-order: 6.0.4(stylelint@17.11.1(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.1(typescript@5.9.3)): dependencies: postcss-scss: 4.0.9(postcss@8.5.14) - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) - stylelint-scss: 7.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.1(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.11.1(typescript@5.9.3)) + stylelint-scss: 7.0.0(stylelint@17.11.1(typescript@5.9.3)) optionalDependencies: postcss: 8.5.14 - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.11.1(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 semver: 7.7.3 - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) - stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.1(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.1(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.11.1(typescript@5.9.3)) - stylelint-config-recommended@18.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.11.1(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.1(typescript@5.9.3) - stylelint-config-standard-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.14)(stylelint@17.11.1(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.14)(stylelint@17.11.0(typescript@5.9.3)) - stylelint-config-standard: 40.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.1(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.14)(stylelint@17.11.1(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.11.1(typescript@5.9.3)) optionalDependencies: postcss: 8.5.14 - stylelint-config-standard@40.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.11.1(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.1(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.11.1(typescript@5.9.3)) - stylelint-order@6.0.4(stylelint@17.11.0(typescript@5.9.3)): + stylelint-order@6.0.4(stylelint@17.11.1(typescript@5.9.3)): dependencies: postcss: 8.5.14 postcss-sorting: 8.0.2(postcss@8.5.14) - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.1(typescript@5.9.3) - stylelint-scss@7.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-scss@7.0.0(stylelint@17.11.1(typescript@5.9.3)): dependencies: css-tree: 3.2.1 is-plain-object: 5.0.0 @@ -13490,13 +13530,13 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.1(typescript@5.9.3) - stylelint-use-logical@2.1.3(stylelint@17.11.0(typescript@5.9.3)): + stylelint-use-logical@2.1.3(stylelint@17.11.1(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.1(typescript@5.9.3) - stylelint@17.11.0(typescript@5.9.3): + stylelint@17.11.1(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -13519,7 +13559,6 @@ snapshots: html-tags: 5.1.0 ignore: 7.0.5 import-meta-resolve: 4.2.0 - is-plain-object: 5.0.0 mathml-tag-names: 4.0.0 meow: 14.1.0 micromatch: 4.0.8 @@ -14004,7 +14043,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.14 - rollup: 4.60.3 + rollup: 4.60.4 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.12.4 @@ -14093,10 +14132,10 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.27(typescript@5.9.3) - vue-tsc@3.2.8(typescript@5.9.3): + vue-tsc@3.2.9(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.28 - '@vue/language-core': 3.2.8 + '@vue/language-core': 3.2.9 typescript: 5.9.3 vue@3.5.27(typescript@5.9.3): @@ -14245,10 +14284,10 @@ snapshots: '@babel/core': 7.26.0 '@babel/preset-env': 7.26.0(@babel/core@7.26.0) '@babel/runtime': 7.25.4 - '@rollup/plugin-babel': 6.1.0(@babel/core@7.26.0)(rollup@4.60.3) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.3) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.3) - '@rollup/plugin-terser': 1.0.0(rollup@4.60.3) + '@rollup/plugin-babel': 6.1.0(@babel/core@7.26.0)(rollup@4.60.4) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) + '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) + '@rollup/plugin-terser': 1.0.0(rollup@4.60.4) '@trickfilm400/rollup-plugin-off-main-thread': 3.0.0-pre1 ajv: 8.18.0 common-tags: 1.8.2 @@ -14257,7 +14296,7 @@ snapshots: fs-extra: 9.1.0 glob: 11.1.0 pretty-bytes: 5.6.0 - rollup: 4.60.3 + rollup: 4.60.4 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -14386,7 +14425,7 @@ snapshots: dependencies: signal-exit: 4.1.0 - ws@8.20.0: {} + ws@8.20.1: {} wsl-utils@0.1.0: dependencies: From 70393f38d21d6f2004cbf468c02e6fcf35c13ad2 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 15 May 2026 17:25:09 +0200 Subject: [PATCH 048/313] feat: add Atom feed for user notifications with API token auth (#2758) --- go.mod | 1 + go.sum | 2 + pkg/db/fixtures/api_tokens.yml | 10 ++ pkg/i18n/lang/en.json | 5 + pkg/mail/testing.go | 14 +++ pkg/models/api_routes.go | 6 + pkg/models/api_tokens.go | 9 ++ pkg/models/api_tokens_expiry_notification.go | 15 ++- pkg/models/api_tokens_test.go | 30 +++++ pkg/models/notifications.go | 78 +++++++++---- pkg/models/notifications_test.go | 84 ++++++++++++++ pkg/notifications/notification.go | 36 ++++++ pkg/notifications/notification_test.go | 100 ++++++++++++++++ pkg/routes/feeds/auth.go | 86 ++++++++++++++ pkg/routes/feeds/auth_test.go | 113 +++++++++++++++++++ pkg/routes/feeds/handler.go | 95 ++++++++++++++++ pkg/routes/feeds/handler_test.go | 73 ++++++++++++ pkg/routes/feeds/main_test.go | 41 +++++++ pkg/routes/routes.go | 12 +- 19 files changed, 787 insertions(+), 23 deletions(-) create mode 100644 pkg/routes/feeds/auth.go create mode 100644 pkg/routes/feeds/auth_test.go create mode 100644 pkg/routes/feeds/handler.go create mode 100644 pkg/routes/feeds/handler_test.go create mode 100644 pkg/routes/feeds/main_test.go diff --git a/go.mod b/go.mod index f759db0c5..a0fd3335b 100644 --- a/go.mod +++ b/go.mod @@ -144,6 +144,7 @@ require ( github.com/goccy/go-yaml v1.18.0 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/css v1.0.1 // indirect + github.com/gorilla/feeds v1.2.0 // indirect github.com/huandu/go-clone v1.7.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect diff --git a/go.sum b/go.sum index fe3bdbab8..a917d62a4 100644 --- a/go.sum +++ b/go.sum @@ -245,6 +245,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc= +github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= diff --git a/pkg/db/fixtures/api_tokens.yml b/pkg/db/fixtures/api_tokens.yml index 2ff417bff..46a97e7f5 100644 --- a/pkg/db/fixtures/api_tokens.yml +++ b/pkg/db/fixtures/api_tokens.yml @@ -68,3 +68,13 @@ owner_id: 15 created: 2024-01-01 00:00:00 # token in plaintext is tk_nocaldav_token_test_000000005678efab +- id: 8 + title: 'feeds access token for user 13' + token_salt: fEdRTk9sR2 + token_hash: c1231ac23940702dcbdf20ae4c125a904780788b091f6d6c56f94f3620a634ec00aac5288659e04174a69a60b20ea86cdfa5 + token_last_eight: feed0013 + permissions: '{"feeds":["access"]}' + expires_at: 2099-01-01 00:00:00 + owner_id: 13 + created: 2024-01-01 00:00:00 + # token in plaintext is tk_feeds_access_token_user_0013_feed0013 diff --git a/pkg/i18n/lang/en.json b/pkg/i18n/lang/en.json index e8b05efb4..b9040d628 100644 --- a/pkg/i18n/lang/en.json +++ b/pkg/i18n/lang/en.json @@ -173,5 +173,10 @@ "since_hours": "one hour|%[1]d hours", "since_minutes": "one minute|%[1]d minutes", "list_last_separator": "and" + }, + "feeds": { + "notifications": { + "title": "Vikunja notifications for %[1]s" + } } } diff --git a/pkg/mail/testing.go b/pkg/mail/testing.go index 02a047586..b7e3f4bc1 100644 --- a/pkg/mail/testing.go +++ b/pkg/mail/testing.go @@ -46,3 +46,17 @@ func AssertSent(t *testing.T, opts *Opts) { assert.True(t, found, "Failed to assert mail '%v' has been sent.", opts) } + +// LastSent returns the most recently captured mail when running under Fake(), +// or nil if no mail has been sent. Intended for tests. +func LastSent() *Opts { + if len(sentMails) == 0 { + return nil + } + return sentMails[len(sentMails)-1] +} + +// ResetSent clears the captured mail buffer. Intended for tests. +func ResetSent() { + sentMails = nil +} diff --git a/pkg/models/api_routes.go b/pkg/models/api_routes.go index 0f8fbcbeb..607274092 100644 --- a/pkg/models/api_routes.go +++ b/pkg/models/api_routes.go @@ -35,6 +35,12 @@ func init() { Method: "ANY", }, } + apiTokenRoutes["feeds"] = APITokenRoute{ + "access": &RouteDetail{ + Path: "/feeds/*", + Method: "GET", + }, + } } type APITokenRoute map[string]*RouteDetail diff --git a/pkg/models/api_tokens.go b/pkg/models/api_tokens.go index 3664f1b3a..8bbe48550 100644 --- a/pkg/models/api_tokens.go +++ b/pkg/models/api_tokens.go @@ -207,6 +207,15 @@ func (t *APIToken) HasCaldavAccess() bool { return slices.Contains(perms, "access") } +// HasFeedsAccess checks whether the token has the feeds access permission. +func (t *APIToken) HasFeedsAccess() bool { + perms, has := t.APIPermissions["feeds"] + if !has { + return false + } + return slices.Contains(perms, "access") +} + // GetTokenFromTokenString returns the full token object from the original token string. func GetTokenFromTokenString(s *xorm.Session, token string) (apiToken *APIToken, err error) { lastEight := token[len(token)-8:] diff --git a/pkg/models/api_tokens_expiry_notification.go b/pkg/models/api_tokens_expiry_notification.go index 8a84d90eb..f99ef435f 100644 --- a/pkg/models/api_tokens_expiry_notification.go +++ b/pkg/models/api_tokens_expiry_notification.go @@ -23,15 +23,23 @@ import ( "code.vikunja.io/api/pkg/user" ) +func init() { + notifications.Register(func() notifications.Notification { return &APITokenExpiringWeekNotification{} }) + notifications.Register(func() notifications.Notification { return &APITokenExpiringDayNotification{} }) +} + // APITokenExpiringWeekNotification is sent 7 days before an API token expires. type APITokenExpiringWeekNotification struct { User *user.User `json:"user"` Token *APIToken `json:"api_token"` } +func (n *APITokenExpiringWeekNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.api_token.expiring.week.subject", n.Token.Title) +} + func (n *APITokenExpiringWeekNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). - Subject(i18n.T(lang, "notifications.api_token.expiring.week.subject", n.Token.Title)). Greeting(i18n.T(lang, "notifications.greeting", n.User.GetName())). Line(i18n.T(lang, "notifications.api_token.expiring.week.message", notifications.EscapeMarkdown(n.Token.Title), n.Token.ExpiresAt.Format("2006-01-02"))). Action(i18n.T(lang, "notifications.api_token.expiring.action"), config.ServicePublicURL.GetString()+"user/settings/api-tokens"). @@ -56,9 +64,12 @@ type APITokenExpiringDayNotification struct { Token *APIToken `json:"api_token"` } +func (n *APITokenExpiringDayNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.api_token.expiring.day.subject", n.Token.Title) +} + func (n *APITokenExpiringDayNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). - Subject(i18n.T(lang, "notifications.api_token.expiring.day.subject", n.Token.Title)). Greeting(i18n.T(lang, "notifications.greeting", n.User.GetName())). Line(i18n.T(lang, "notifications.api_token.expiring.day.message", notifications.EscapeMarkdown(n.Token.Title), n.Token.ExpiresAt.Format("2006-01-02"))). Action(i18n.T(lang, "notifications.api_token.expiring.action"), config.ServicePublicURL.GetString()+"user/settings/api-tokens"). diff --git a/pkg/models/api_tokens_test.go b/pkg/models/api_tokens_test.go index 6677c09fa..261de26bd 100644 --- a/pkg/models/api_tokens_test.go +++ b/pkg/models/api_tokens_test.go @@ -125,6 +125,36 @@ func TestAPIToken_HasCaldavAccess(t *testing.T) { }) } +func TestAPIToken_HasFeedsAccess(t *testing.T) { + t.Run("has feeds access", func(t *testing.T) { + token := &APIToken{ + APIPermissions: APIPermissions{"feeds": {"access"}}, + } + assert.True(t, token.HasFeedsAccess()) + }) + t.Run("no feeds group", func(t *testing.T) { + token := &APIToken{ + APIPermissions: APIPermissions{"tasks": {"read_all"}}, + } + assert.False(t, token.HasFeedsAccess()) + }) + t.Run("feeds group but wrong permission", func(t *testing.T) { + token := &APIToken{ + APIPermissions: APIPermissions{"feeds": {"read_all"}}, + } + assert.False(t, token.HasFeedsAccess()) + }) + t.Run("feeds access among other permissions", func(t *testing.T) { + token := &APIToken{ + APIPermissions: APIPermissions{ + "tasks": {"read_all", "update"}, + "feeds": {"access"}, + }, + } + assert.True(t, token.HasFeedsAccess()) + }) +} + func TestAPIToken_GetTokenFromTokenString(t *testing.T) { t.Run("valid token", func(t *testing.T) { s := db.NewSession() diff --git a/pkg/models/notifications.go b/pkg/models/notifications.go index 3b1e4680a..4f27d04f4 100644 --- a/pkg/models/notifications.go +++ b/pkg/models/notifications.go @@ -32,6 +32,16 @@ import ( "code.vikunja.io/api/pkg/utils" ) +func init() { + notifications.Register(func() notifications.Notification { return &ReminderDueNotification{} }) + notifications.Register(func() notifications.Notification { return &TaskCommentNotification{} }) + notifications.Register(func() notifications.Notification { return &TaskAssignedNotification{} }) + notifications.Register(func() notifications.Notification { return &TaskDeletedNotification{} }) + notifications.Register(func() notifications.Notification { return &ProjectCreatedNotification{} }) + notifications.Register(func() notifications.Notification { return &TeamMemberAddedNotification{} }) + notifications.Register(func() notifications.Notification { return &UserMentionedInTaskNotification{} }) +} + // getDoerAvatarDataURI returns the avatar data URI for a user, for use in email headers. func getDoerAvatarDataURI(doer *user.User) string { provider := avatar.GetProvider(doer) @@ -55,12 +65,16 @@ type ReminderDueNotification struct { TaskReminder *TaskReminder `json:"reminder"` } +// ToTitle returns the translated one-line title for ReminderDueNotification +func (n *ReminderDueNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.task.reminder.subject", n.Task.Title, n.Project.Title) +} + // ToMail returns the mail notification for ReminderDueNotification func (n *ReminderDueNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). IncludeLinkToSettings(lang). To(n.User.Email). - Subject(i18n.T(lang, "notifications.task.reminder.subject", n.Task.Title, n.Project.Title)). Greeting(i18n.T(lang, "notifications.greeting", n.User.GetName())). Line(i18n.T(lang, "notifications.task.reminder.message", notifications.EscapeMarkdown(n.Task.Title), notifications.EscapeMarkdown(n.Project.Title))). Action(i18n.T(lang, "notifications.common.actions.open_task"), config.ServicePublicURL.GetString()+"tasks/"+strconv.FormatInt(n.Task.ID, 10)). @@ -98,6 +112,14 @@ func (n *TaskCommentNotification) SubjectID() int64 { return n.Comment.ID } +// ToTitle returns the translated one-line title for TaskCommentNotification +func (n *TaskCommentNotification) ToTitle(lang string) string { + if n.Mentioned { + return i18n.T(lang, "notifications.task.comment.mentioned_subject", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier()) + } + return i18n.T(lang, "notifications.task.comment.subject", n.Task.Title, n.Task.GetFullIdentifier()) +} + // ToMail returns the mail notification for TaskCommentNotification func (n *TaskCommentNotification) ToMail(lang string) *notifications.Mail { s := db.NewSession() @@ -106,14 +128,12 @@ func (n *TaskCommentNotification) ToMail(lang string) *notifications.Mail { mail := notifications.NewMail(). Conversational(). - From(n.Doer.GetNameAndFromEmail()). - Subject(i18n.T(lang, "notifications.task.comment.subject", n.Task.Title, n.Task.GetFullIdentifier())) + From(n.Doer.GetNameAndFromEmail()) // Add header line action := i18n.T(lang, "notifications.common.actions.left_comment", n.Doer.GetName()) if n.Mentioned { action = i18n.T(lang, "notifications.common.actions.mentioned_you_comment", n.Doer.GetName()) - mail.Subject(i18n.T(lang, "notifications.task.comment.mentioned_subject", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier())) } headerLine := notifications.CreateConversationalHeader( @@ -158,13 +178,23 @@ type TaskAssignedNotification struct { Project *Project `json:"project"` } +// ToTitle returns the translated one-line title for TaskAssignedNotification +func (n *TaskAssignedNotification) ToTitle(lang string) string { + if n.Target.ID == n.Assignee.ID { + return i18n.T(lang, "notifications.task.assigned.subject_to_assignee", n.Task.Title, n.Task.GetFullIdentifier()) + } + if n.Doer.ID == n.Assignee.ID { + return i18n.T(lang, "notifications.task.assigned.subject_to_others_self", n.Task.Title, n.Task.GetFullIdentifier(), n.Doer.GetName()) + } + return i18n.T(lang, "notifications.task.assigned.subject_to_others", n.Task.Title, n.Task.GetFullIdentifier(), n.Assignee.GetName()) +} + // ToMail returns the mail notification for TaskAssignedNotification func (n *TaskAssignedNotification) ToMail(lang string) *notifications.Mail { if n.Target.ID == n.Assignee.ID { // Notification to the assignee return notifications.NewMail(). From(n.Doer.GetNameAndFromEmail()). - Subject(i18n.T(lang, "notifications.task.assigned.subject_to_assignee", n.Task.Title, n.Task.GetFullIdentifier())). Greeting(i18n.T(lang, "notifications.greeting", n.Target.GetName())). Line(i18n.T(lang, "notifications.task.assigned.message_to_assignee", notifications.EscapeMarkdown(n.Doer.GetName()), notifications.EscapeMarkdown(n.Task.Title))). Action(i18n.T(lang, "notifications.common.actions.open_task"), n.Task.GetFrontendURL()). @@ -175,7 +205,6 @@ func (n *TaskAssignedNotification) ToMail(lang string) *notifications.Mail { if n.Doer.ID == n.Assignee.ID { return notifications.NewMail(). From(n.Doer.GetNameAndFromEmail()). - Subject(i18n.T(lang, "notifications.task.assigned.subject_to_others_self", n.Task.Title, n.Task.GetFullIdentifier(), n.Doer.GetName())). Greeting(i18n.T(lang, "notifications.greeting", n.Target.GetName())). Line(i18n.T(lang, "notifications.task.assigned.message_to_others_self", notifications.EscapeMarkdown(n.Doer.GetName()))). Action(i18n.T(lang, "notifications.common.actions.open_task"), n.Task.GetFrontendURL()). @@ -185,7 +214,6 @@ func (n *TaskAssignedNotification) ToMail(lang string) *notifications.Mail { // Notification to others about assignment return notifications.NewMail(). From(n.Doer.GetNameAndFromEmail()). - Subject(i18n.T(lang, "notifications.task.assigned.subject_to_others", n.Task.Title, n.Task.GetFullIdentifier(), n.Assignee.GetName())). Greeting(i18n.T(lang, "notifications.greeting", n.Target.GetName())). Line(i18n.T(lang, "notifications.task.assigned.message_to_others", notifications.EscapeMarkdown(n.Doer.GetName()), notifications.EscapeMarkdown(n.Assignee.GetName()))). Action(i18n.T(lang, "notifications.common.actions.open_task"), n.Task.GetFrontendURL()). @@ -213,10 +241,14 @@ type TaskDeletedNotification struct { Task *Task `json:"task"` } +// ToTitle returns the translated one-line title for TaskDeletedNotification +func (n *TaskDeletedNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.task.deleted.subject", n.Task.Title, n.Task.GetFullIdentifier()) +} + // ToMail returns the mail notification for TaskDeletedNotification func (n *TaskDeletedNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). - Subject(i18n.T(lang, "notifications.task.deleted.subject", n.Task.Title, n.Task.GetFullIdentifier())). Line(i18n.T(lang, "notifications.task.deleted.message", notifications.EscapeMarkdown(n.Doer.GetName()), notifications.EscapeMarkdown(n.Task.Title), notifications.EscapeMarkdown(n.Task.GetFullIdentifier()))) } @@ -241,10 +273,14 @@ type ProjectCreatedNotification struct { Project *Project `json:"project"` } +// ToTitle returns the translated one-line title for ProjectCreatedNotification +func (n *ProjectCreatedNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.project.created", n.Doer.GetName(), n.Project.Title) +} + // ToMail returns the mail notification for ProjectCreatedNotification func (n *ProjectCreatedNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). - Subject(i18n.T(lang, "notifications.project.created", n.Doer.GetName(), n.Project.Title)). Line(i18n.T(lang, "notifications.project.created", notifications.EscapeMarkdown(n.Doer.GetName()), notifications.EscapeMarkdown(n.Project.Title))). Action(i18n.T(lang, "notifications.common.actions.open_project"), config.ServicePublicURL.GetString()+"projects/") } @@ -266,10 +302,14 @@ type TeamMemberAddedNotification struct { Team *Team `json:"team"` } +// ToTitle returns the translated one-line title for TeamMemberAddedNotification +func (n *TeamMemberAddedNotification) ToTitle(lang string) string { + return i18n.T(lang, "notifications.team.member_added.subject", n.Doer.GetName(), n.Team.Name) +} + // ToMail returns the mail notification for TeamMemberAddedNotification func (n *TeamMemberAddedNotification) ToMail(lang string) *notifications.Mail { return notifications.NewMail(). - Subject(i18n.T(lang, "notifications.team.member_added.subject", n.Doer.GetName(), n.Team.Name)). From(n.Doer.GetNameAndFromEmail()). Greeting(i18n.T(lang, "notifications.greeting", n.Member.GetName())). Line(i18n.T(lang, "notifications.team.member_added.message", notifications.EscapeMarkdown(n.Doer.GetName()), notifications.EscapeMarkdown(n.Team.Name))). @@ -385,23 +425,23 @@ func (n *UserMentionedInTaskNotification) SubjectID() int64 { return n.Task.ID } +// ToTitle returns the translated one-line title for UserMentionedInTaskNotification +func (n *UserMentionedInTaskNotification) ToTitle(lang string) string { + if n.IsNew { + return i18n.T(lang, "notifications.task.mentioned.subject_new", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier()) + } + return i18n.T(lang, "notifications.task.mentioned.subject", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier()) +} + // ToMail returns the mail notification for UserMentionedInTaskNotification func (n *UserMentionedInTaskNotification) ToMail(lang string) *notifications.Mail { s := db.NewSession() defer s.Close() formattedDescription := formatMentionsForEmail(s, n.Task.Description) - var subject string - if n.IsNew { - subject = i18n.T(lang, "notifications.task.mentioned.subject_new", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier()) - } else { - subject = i18n.T(lang, "notifications.task.mentioned.subject", n.Doer.GetName(), n.Task.Title, n.Task.GetFullIdentifier()) - } - mail := notifications.NewMail(). Conversational(). - From(n.Doer.GetNameAndFromEmail()). - Subject(subject) + From(n.Doer.GetNameAndFromEmail()) // Add header line action := i18n.T(lang, "notifications.common.actions.mentioned_you", n.Doer.GetName()) diff --git a/pkg/models/notifications_test.go b/pkg/models/notifications_test.go index 9e777d896..1aac48239 100644 --- a/pkg/models/notifications_test.go +++ b/pkg/models/notifications_test.go @@ -142,6 +142,90 @@ func TestUndoneTasksOverdueNotification_TitleIsMarkdownEscaped(t *testing.T) { "malicious title must render as literal text") } +func TestTaskCommentNotification_ToTitle(t *testing.T) { + doer := &user.User{ID: 1, Name: "alice", Username: "alice"} + task := &Task{ID: 42, Title: "Take out trash", Index: 7} + + t.Run("regular comment", func(t *testing.T) { + n := &TaskCommentNotification{Doer: doer, Task: task, Mentioned: false} + title := n.ToTitle("en") + assert.Contains(t, title, "Take out trash") + assert.NotContains(t, title, "alice", "regular comment title should not mention the doer") + }) + + t.Run("mention switches title", func(t *testing.T) { + n := &TaskCommentNotification{Doer: doer, Task: task, Mentioned: true} + title := n.ToTitle("en") + assert.Contains(t, title, "alice", "mentioned title should mention the doer") + assert.Contains(t, title, "Take out trash") + }) + + t.Run("regular and mentioned produce different titles", func(t *testing.T) { + regular := (&TaskCommentNotification{Doer: doer, Task: task, Mentioned: false}).ToTitle("en") + mentioned := (&TaskCommentNotification{Doer: doer, Task: task, Mentioned: true}).ToTitle("en") + assert.NotEqual(t, regular, mentioned) + }) +} + +func TestTaskAssignedNotification_ToTitle(t *testing.T) { + doer := &user.User{ID: 1, Name: "alice", Username: "alice"} + assignee := &user.User{ID: 2, Name: "bob", Username: "bob"} + third := &user.User{ID: 3, Name: "carol", Username: "carol"} + task := &Task{ID: 42, Title: "Take out trash", Index: 7} + + t.Run("to assignee themself", func(t *testing.T) { + n := &TaskAssignedNotification{Doer: doer, Task: task, Assignee: assignee, Target: assignee} + title := n.ToTitle("en") + assert.Contains(t, title, "Take out trash") + }) + + t.Run("doer assigned to themself", func(t *testing.T) { + n := &TaskAssignedNotification{Doer: doer, Task: task, Assignee: doer, Target: third} + title := n.ToTitle("en") + assert.Contains(t, title, "alice") + }) + + t.Run("doer assigned someone else, target is third party", func(t *testing.T) { + n := &TaskAssignedNotification{Doer: doer, Task: task, Assignee: assignee, Target: third} + title := n.ToTitle("en") + assert.Contains(t, title, "bob") + }) + + t.Run("three branches produce three distinct titles", func(t *testing.T) { + a := (&TaskAssignedNotification{Doer: doer, Task: task, Assignee: assignee, Target: assignee}).ToTitle("en") + b := (&TaskAssignedNotification{Doer: doer, Task: task, Assignee: doer, Target: third}).ToTitle("en") + c := (&TaskAssignedNotification{Doer: doer, Task: task, Assignee: assignee, Target: third}).ToTitle("en") + assert.NotEqual(t, a, b) + assert.NotEqual(t, a, c) + assert.NotEqual(t, b, c) + }) +} + +func TestUserMentionedInTaskNotification_ToTitle(t *testing.T) { + doer := &user.User{ID: 1, Name: "alice", Username: "alice"} + task := &Task{ID: 42, Title: "Take out trash", Index: 7} + + t.Run("existing task", func(t *testing.T) { + n := &UserMentionedInTaskNotification{Doer: doer, Task: task, IsNew: false} + title := n.ToTitle("en") + assert.Contains(t, title, "alice") + assert.Contains(t, title, "Take out trash") + }) + + t.Run("new task", func(t *testing.T) { + n := &UserMentionedInTaskNotification{Doer: doer, Task: task, IsNew: true} + title := n.ToTitle("en") + assert.Contains(t, title, "alice") + assert.Contains(t, title, "Take out trash") + }) + + t.Run("new task and existing task produce different titles", func(t *testing.T) { + existing := (&UserMentionedInTaskNotification{Doer: doer, Task: task, IsNew: false}).ToTitle("en") + newOne := (&UserMentionedInTaskNotification{Doer: doer, Task: task, IsNew: true}).ToTitle("en") + assert.NotEqual(t, existing, newOne) + }) +} + func TestReminderDueNotification_TitleIsMarkdownEscaped(t *testing.T) { originalPublicURL := config.ServicePublicURL.GetString() t.Cleanup(func() { config.ServicePublicURL.Set(originalPublicURL) }) diff --git a/pkg/notifications/notification.go b/pkg/notifications/notification.go index d50735793..cdb795dfb 100644 --- a/pkg/notifications/notification.go +++ b/pkg/notifications/notification.go @@ -45,6 +45,36 @@ type ThreadID interface { ThreadID() string } +// Titler is an optional capability for notifications that can render a +// one-line, translated title. Used as the mail subject when ToMail does not +// set one explicitly, and as the item title in the notifications feed. +type Titler interface { + ToTitle(lang string) string +} + +var registry = map[string]func() Notification{} + +// Register makes a notification type discoverable by name. It should be +// called from init() in the package that defines the type. Only notifications +// that persist to the database need to register, since only persisted +// notifications are re-hydrated from JSON (e.g. by the feed handler). +// The name is derived from the notification's own Name() method, so it stays +// in one place. +func Register(factory func() Notification) { + registry[factory().Name()] = factory +} + +// Lookup returns a fresh, empty instance of the notification type registered +// under the given name. The second return value is false if no type is +// registered with that name. +func Lookup(name string) (Notification, bool) { + f, ok := registry[name] + if !ok { + return nil, false + } + return f(), true +} + // Notifiable is an entity which can be notified. Usually a user. type Notifiable interface { // RouteForMail should return the email address this notifiable has. @@ -91,6 +121,12 @@ func notifyMail(notifiable Notifiable, notification Notification) error { return nil } + if mail.subject == "" { + if t, is := notification.(Titler); is { + mail.subject = t.ToTitle(notifiable.Lang()) + } + } + to, err := notifiable.RouteForMail() if err != nil { return err diff --git a/pkg/notifications/notification_test.go b/pkg/notifications/notification_test.go index f15eb350b..54b0be9fe 100644 --- a/pkg/notifications/notification_test.go +++ b/pkg/notifications/notification_test.go @@ -20,7 +20,9 @@ import ( "testing" "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/mail" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "xorm.io/xorm" "xorm.io/xorm/schemas" @@ -74,6 +76,68 @@ func (t *testNotifiable) Lang() string { return t.Language } +// titlerNoSubjectNotification implements Titler and intentionally omits a +// Subject from ToMail so the fallback path is exercised. +type titlerNoSubjectNotification struct { + title string +} + +func (n *titlerNoSubjectNotification) ToMail(_ string) *Mail { + return NewMail().Line("body") +} +func (n *titlerNoSubjectNotification) ToDB() interface{} { return nil } +func (n *titlerNoSubjectNotification) Name() string { return "test.titler.no.subject" } +func (n *titlerNoSubjectNotification) ToTitle(_ string) string { return n.title } + +// titlerWithExplicitSubjectNotification implements Titler but also sets an +// explicit subject in ToMail; that explicit subject must win. +type titlerWithExplicitSubjectNotification struct { + title string + subject string +} + +func (n *titlerWithExplicitSubjectNotification) ToMail(_ string) *Mail { + return NewMail().Subject(n.subject).Line("body") +} +func (n *titlerWithExplicitSubjectNotification) ToDB() interface{} { return nil } +func (n *titlerWithExplicitSubjectNotification) Name() string { return "test.titler.with.subject" } +func (n *titlerWithExplicitSubjectNotification) ToTitle(_ string) string { return n.title } + +// noTitlerNotification is the control: no Titler, no Subject, fallback must +// leave subject empty without panicking. +type noTitlerNotification struct{} + +func (n *noTitlerNotification) ToMail(_ string) *Mail { return NewMail().Line("body") } +func (n *noTitlerNotification) ToDB() interface{} { return nil } +func (n *noTitlerNotification) Name() string { return "test.no.titler" } + +// titlerRegisteredNotification is used to exercise Register/Lookup. +type titlerRegisteredNotification struct { + Title string `json:"title"` +} + +func (n *titlerRegisteredNotification) ToMail(_ string) *Mail { return NewMail().Line("body") } +func (n *titlerRegisteredNotification) ToDB() interface{} { return n } +func (n *titlerRegisteredNotification) Name() string { return "test.registry.titler" } +func (n *titlerRegisteredNotification) ToTitle(_ string) string { return n.Title } + +func TestRegistry(t *testing.T) { + Register(func() Notification { return &titlerRegisteredNotification{} }) + + t.Run("known name returns fresh instance", func(t *testing.T) { + n, ok := Lookup("test.registry.titler") + require.True(t, ok) + require.NotNil(t, n) + _, ok = n.(*titlerRegisteredNotification) + assert.True(t, ok) + }) + + t.Run("unknown name returns false", func(t *testing.T) { + _, ok := Lookup("does.not.exist") + assert.False(t, ok) + }) +} + func TestNotify(t *testing.T) { t.Run("normal", func(t *testing.T) { @@ -111,6 +175,42 @@ func TestNotify(t *testing.T) { db.AssertExists(t, "notifications", vals, true) }) + t.Run("subject fallback uses ToTitle when ToMail omits Subject", func(t *testing.T) { + mail.ResetSent() + tnf := &testNotifiable{ShouldSendNotification: true, Language: "en"} + + err := notifyMail(tnf, &titlerNoSubjectNotification{title: "From ToTitle"}) + require.NoError(t, err) + + sent := mail.LastSent() + require.NotNil(t, sent) + assert.Equal(t, "From ToTitle", sent.Subject) + }) + + t.Run("explicit Subject in ToMail wins over ToTitle", func(t *testing.T) { + mail.ResetSent() + tnf := &testNotifiable{ShouldSendNotification: true, Language: "en"} + + err := notifyMail(tnf, &titlerWithExplicitSubjectNotification{title: "From ToTitle", subject: "Explicit"}) + require.NoError(t, err) + + sent := mail.LastSent() + require.NotNil(t, sent) + assert.Equal(t, "Explicit", sent.Subject) + }) + + t.Run("no fallback when notification does not implement Titler", func(t *testing.T) { + mail.ResetSent() + tnf := &testNotifiable{ShouldSendNotification: true, Language: "en"} + + err := notifyMail(tnf, &noTitlerNotification{}) + require.NoError(t, err) + + sent := mail.LastSent() + require.NotNil(t, sent) + assert.Empty(t, sent.Subject) + }) + t.Run("disabled notifiable", func(t *testing.T) { s := db.NewSession() diff --git a/pkg/routes/feeds/auth.go b/pkg/routes/feeds/auth.go new file mode 100644 index 000000000..419fd2ccd --- /dev/null +++ b/pkg/routes/feeds/auth.go @@ -0,0 +1,86 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package feeds + +import ( + "strings" + + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/log" + "code.vikunja.io/api/pkg/models" + "code.vikunja.io/api/pkg/user" + "xorm.io/xorm" + + "github.com/labstack/echo/v5" +) + +func checkAPIToken(s *xorm.Session, username, token string) (*user.User, error) { + apiToken, u, err := models.ValidateTokenAndGetOwner(s, token) + if err != nil { + return nil, err + } + if apiToken == nil || u == nil { + return nil, nil + } + + if !apiToken.HasFeedsAccess() { + log.Debugf("[feeds auth] API token %d does not have feeds access permission", apiToken.ID) + return nil, nil + } + + if u.Username != username { + log.Debugf("[feeds auth] API token %d owner %s does not match provided username %s", apiToken.ID, u.Username, username) + return nil, nil + } + + return u, nil +} + +// BasicAuth authenticates feed requests. Only API tokens are accepted — +// password and LDAP credentials are rejected outright because feed URLs are +// commonly exported, shared, or cached by feed readers. +func BasicAuth(c *echo.Context, username, password string) (bool, error) { + if !strings.HasPrefix(password, models.APITokenPrefix) { + return false, nil + } + // GetTokenFromTokenString slices password[len-8:] without a length check, + // so a stray "tk_" or other short prefix-only string would panic before + // the credentials could be rejected. Real tokens are far longer than + // prefix+8, so anything shorter is invalid by construction. + if len(password) < len(models.APITokenPrefix)+8 { + return false, nil + } + + s := db.NewSession() + defer s.Close() + + u, err := checkAPIToken(s, username, password) + if err != nil { + log.Errorf("Error during API token auth for feeds: %v", err) + return false, nil + } + if u == nil { + return false, nil + } + if u.IsBot() { + log.Warningf("Feed auth rejected for bot user %d", u.ID) + return false, nil + } + + c.Set("userBasicAuth", u) + return true, nil +} diff --git a/pkg/routes/feeds/auth_test.go b/pkg/routes/feeds/auth_test.go new file mode 100644 index 000000000..5a8359fef --- /dev/null +++ b/pkg/routes/feeds/auth_test.go @@ -0,0 +1,113 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package feeds + +import ( + "net/http" + "net/http/httptest" + "testing" + + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/user" + + "github.com/labstack/echo/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + feedsTokenUser13Valid = "tk_feeds_access_token_user_0013_feed0013" // owner_id 13, feeds scope + caldavOnlyToken = "tk_caldav_api_token_test_00000000aabbccdd" // owner_id 15, caldav scope only + expiredTasksToken = "tk_a5e6f92ddbad68f49ee2c63e52174db0235008c8" // expired + tasksScopedTokenOwner1 = "tk_2eef46f40ebab3304919ab2e7e39993f75f29d2e" // owner_id 1, no feeds scope +) + +func newContext() *echo.Context { + e := echo.New() + req := httptest.NewRequest(http.MethodGet, "/feeds/notifications.atom", nil) + rec := httptest.NewRecorder() + return e.NewContext(req, rec) +} + +func TestBasicAuth(t *testing.T) { + db.LoadAndAssertFixtures(t) + + t.Run("rejects non-token password without touching db", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user1", "plaintextpassword") + require.NoError(t, err) + assert.False(t, ok) + assert.Nil(t, c.Get("userBasicAuth")) + }) + + t.Run("rejects unknown token", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user1", "tk_nonexistent_token_value_aaaaaaaaaaaaaaaa") + require.NoError(t, err) + assert.False(t, ok) + }) + + t.Run("rejects token shorter than prefix+8 without panicking", func(t *testing.T) { + // Real tokens are far longer; anything shorter is invalid by + // construction and would otherwise panic inside GetTokenFromTokenString. + for _, short := range []string{"tk_", "tk_abc", "tk_1234567"} { + c := newContext() + ok, err := BasicAuth(c, "user1", short) + require.NoError(t, err) + assert.False(t, ok, "short token %q must be rejected", short) + } + }) + + t.Run("rejects token whose owner username does not match", func(t *testing.T) { + c := newContext() + // feedsTokenUser13Valid belongs to user 13; supply a different username. + ok, err := BasicAuth(c, "wrongname", feedsTokenUser13Valid) + require.NoError(t, err) + assert.False(t, ok) + }) + + t.Run("rejects token without feeds scope", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user1", tasksScopedTokenOwner1) + require.NoError(t, err) + assert.False(t, ok) + }) + + t.Run("rejects token with caldav scope but no feeds scope", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user15", caldavOnlyToken) + require.NoError(t, err) + assert.False(t, ok) + }) + + t.Run("rejects expired token", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user1", expiredTasksToken) + require.NoError(t, err) + assert.False(t, ok) + }) + + t.Run("accepts valid token with feeds scope", func(t *testing.T) { + c := newContext() + ok, err := BasicAuth(c, "user13", feedsTokenUser13Valid) + require.NoError(t, err) + assert.True(t, ok) + u, is := c.Get("userBasicAuth").(*user.User) + require.True(t, is) + assert.Equal(t, int64(13), u.ID) + }) +} diff --git a/pkg/routes/feeds/handler.go b/pkg/routes/feeds/handler.go new file mode 100644 index 000000000..9d0794c76 --- /dev/null +++ b/pkg/routes/feeds/handler.go @@ -0,0 +1,95 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package feeds + +import ( + "encoding/json" + "net/http" + "strconv" + "time" + + "code.vikunja.io/api/pkg/config" + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/i18n" + "code.vikunja.io/api/pkg/notifications" + "code.vikunja.io/api/pkg/user" + + "github.com/gorilla/feeds" + "github.com/labstack/echo/v5" +) + +const feedItemLimit = 50 + +// NotificationsAtomFeed serves the authenticated user's notifications as an +// Atom feed. Notifications are not marked as read by being fetched here. +func NotificationsAtomFeed(c *echo.Context) error { + u, ok := c.Get("userBasicAuth").(*user.User) + if !ok { + return echo.NewHTTPError(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized)) + } + + s := db.NewSession() + defer s.Close() + + rows, _, _, err := notifications.GetNotificationsForUser(s, u.ID, feedItemLimit, 0) + if err != nil { + return err + } + + publicURL := config.ServicePublicURL.GetString() + feed := &feeds.Feed{ + Title: i18n.T(u.Language, "feeds.notifications.title", u.GetName()), + Link: &feeds.Link{Href: publicURL + "feeds/notifications.atom"}, + Author: &feeds.Author{Name: u.GetName()}, + Updated: time.Now(), + } + + for _, row := range rows { + typed, ok := notifications.Lookup(row.Name) + if !ok { + continue + } + + raw, err := json.Marshal(row.Notification) + if err != nil { + continue + } + if err := json.Unmarshal(raw, typed); err != nil { + continue + } + + titler, ok := typed.(notifications.Titler) + if !ok { + continue + } + + feed.Items = append(feed.Items, &feeds.Item{ + Id: "vikunja-notification-" + strconv.FormatInt(row.ID, 10), + Title: titler.ToTitle(u.Language), + Created: row.Created, + Link: &feeds.Link{Href: publicURL}, + }) + } + + atom, err := feed.ToAtom() + if err != nil { + return err + } + + c.Response().Header().Set(echo.HeaderContentType, "application/atom+xml; charset=utf-8") + return c.String(http.StatusOK, atom) +} diff --git a/pkg/routes/feeds/handler_test.go b/pkg/routes/feeds/handler_test.go new file mode 100644 index 000000000..dfc984d68 --- /dev/null +++ b/pkg/routes/feeds/handler_test.go @@ -0,0 +1,73 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package feeds + +import ( + "encoding/xml" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/user" + + "github.com/labstack/echo/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNotificationsAtomFeed(t *testing.T) { + db.LoadAndAssertFixtures(t) + + t.Run("returns valid atom XML for authenticated user with no notifications", func(t *testing.T) { + e := echo.New() + req := httptest.NewRequest(http.MethodGet, "/feeds/notifications.atom", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + c.Set("userBasicAuth", &user.User{ID: 1, Name: "User 1", Username: "user1", Language: "en"}) + + err := NotificationsAtomFeed(c) + require.NoError(t, err) + + assert.Equal(t, http.StatusOK, rec.Code) + assert.True(t, strings.HasPrefix(rec.Header().Get(echo.HeaderContentType), "application/atom+xml"), + "unexpected content type: %s", rec.Header().Get(echo.HeaderContentType)) + + // Must be parseable as XML. + var doc struct { + XMLName xml.Name `xml:"feed"` + Title string `xml:"title"` + } + require.NoError(t, xml.Unmarshal(rec.Body.Bytes(), &doc)) + assert.Contains(t, doc.Title, "User 1", "feed title should include the user's name") + }) + + t.Run("returns 401 when context has no authenticated user", func(t *testing.T) { + e := echo.New() + req := httptest.NewRequest(http.MethodGet, "/feeds/notifications.atom", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err := NotificationsAtomFeed(c) + require.Error(t, err) + httpErr, ok := err.(*echo.HTTPError) + require.True(t, ok, "expected echo.HTTPError, got %T", err) + assert.Equal(t, http.StatusUnauthorized, httpErr.Code) + }) +} diff --git a/pkg/routes/feeds/main_test.go b/pkg/routes/feeds/main_test.go new file mode 100644 index 000000000..6f58af476 --- /dev/null +++ b/pkg/routes/feeds/main_test.go @@ -0,0 +1,41 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package feeds + +import ( + "os" + "testing" + + "code.vikunja.io/api/pkg/config" + "code.vikunja.io/api/pkg/events" + "code.vikunja.io/api/pkg/files" + "code.vikunja.io/api/pkg/i18n" + "code.vikunja.io/api/pkg/log" + "code.vikunja.io/api/pkg/models" + "code.vikunja.io/api/pkg/user" +) + +func TestMain(m *testing.M) { + log.InitLogger() + config.InitDefaultConfig() + i18n.Init() + files.InitTests() + user.InitTests() + models.SetupTests() + events.Fake() + os.Exit(m.Run()) +} diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index e37927e5f..c4ce0a002 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -81,6 +81,7 @@ import ( apiv1 "code.vikunja.io/api/pkg/routes/api/v1" adminapi "code.vikunja.io/api/pkg/routes/api/v1/admin" "code.vikunja.io/api/pkg/routes/caldav" + "code.vikunja.io/api/pkg/routes/feeds" "code.vikunja.io/api/pkg/version" "code.vikunja.io/api/pkg/web/handler" ws "code.vikunja.io/api/pkg/websocket" @@ -259,6 +260,11 @@ func RegisterRoutes(e *echo.Echo) { registerCalDavRoutes(c) } + // Feeds routes (Atom feed for user notifications) + f := e.Group("/feeds") + f.Use(middleware.BasicAuth(feeds.BasicAuth)) + f.GET("/notifications.atom", feeds.NotificationsAtomFeed) + // healthcheck e.GET("/health", HealthcheckHandler) @@ -282,8 +288,10 @@ func RegisterRoutes(e *echo.Echo) { // Since it is not possible to register this middleware just for the api group, // we just disable it when for caldav requests. // Caldav requires OPTIONS requests to be answered in a specific manner, - // not doing this would break the caldav implementation - return strings.HasPrefix(context.Path(), "/dav") + // not doing this would break the caldav implementation. + // Feed readers are server-side and don't need CORS either. + p := context.Path() + return strings.HasPrefix(p, "/dav") || strings.HasPrefix(p, "/feeds") }, })) } From fc373ae963202cadf2e059030907b978c43091e1 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Fri, 15 May 2026 14:11:33 +0000 Subject: [PATCH 049/313] test(trello): serve testimage from local server instead of vikunja.io Mirrors the Todoist migration test setup so TestConvertTrelloToVikunja no longer depends on https://vikunja.io/testimage.jpg being reachable. --- pkg/modules/migration/trello/trello_test.go | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/pkg/modules/migration/trello/trello_test.go b/pkg/modules/migration/trello/trello_test.go index 563b4afc8..970f9c3cb 100644 --- a/pkg/modules/migration/trello/trello_test.go +++ b/pkg/modules/migration/trello/trello_test.go @@ -18,10 +18,13 @@ package trello import ( "bytes" + "net/http" + "net/http/httptest" "os" "testing" "time" + "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/models" @@ -228,7 +231,7 @@ func getTestBoard(t *testing.T) ([]*trello.Board, time.Time) { }, }, } - trelloData[0].Prefs.BackgroundImage = "https://vikunja.io/testimage.jpg" // Using an image which we are hosting, so it'll still be up + trelloData[0].Prefs.BackgroundImage = "https://vikunja.io/testimage.jpg" // Overridden in TestConvertTrelloToVikunja to point at a local test server. return trelloData, time1 } @@ -239,6 +242,23 @@ func TestConvertTrelloToVikunja(t *testing.T) { exampleFile, err := os.ReadFile("../testimage.jpg") require.NoError(t, err) + // Serve the attachment from a local test server so the test does not depend + // on an external host being reachable. The SSRF-safe client used by + // migration.DownloadFile rejects non-routable IPs by default, so allow them + // for the duration of this test. + prevAllowNonRoutable := config.OutgoingRequestsAllowNonRoutableIPs.GetBool() + config.OutgoingRequestsAllowNonRoutableIPs.Set("true") + t.Cleanup(func() { + config.OutgoingRequestsAllowNonRoutableIPs.Set(prevAllowNonRoutable) + }) + attachmentServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write(exampleFile) + })) + t.Cleanup(attachmentServer.Close) + + trelloData[0].Prefs.BackgroundImage = attachmentServer.URL + "/testimage.jpg" + trelloData[0].Lists[0].Cards[0].Attachments[0].URL = attachmentServer.URL + "/testimage.jpg" + expectedHierarchyOrg := map[string][]*models.ProjectWithTasksAndBuckets{ "orgid": { { From 6b143078960c9b27079d3a09c66ea51a803a4bbe Mon Sep 17 00:00:00 2001 From: Tink bot Date: Fri, 15 May 2026 15:01:19 +0000 Subject: [PATCH 050/313] test(trello): drop redundant BackgroundImage assignment in getTestBoard --- pkg/modules/migration/trello/trello_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/modules/migration/trello/trello_test.go b/pkg/modules/migration/trello/trello_test.go index 970f9c3cb..7f64724b9 100644 --- a/pkg/modules/migration/trello/trello_test.go +++ b/pkg/modules/migration/trello/trello_test.go @@ -231,7 +231,6 @@ func getTestBoard(t *testing.T) ([]*trello.Board, time.Time) { }, }, } - trelloData[0].Prefs.BackgroundImage = "https://vikunja.io/testimage.jpg" // Overridden in TestConvertTrelloToVikunja to point at a local test server. return trelloData, time1 } From b9e3bb95fae565cfb5a8ce3319fb10a1b8f622b6 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 15 May 2026 19:28:29 +0200 Subject: [PATCH 051/313] feat(frontend): add Atom feed settings page and notifications discovery (#2760) --- frontend/src/components/misc/Icon.ts | 2 + .../notifications/Notifications.vue | 26 ++++++- frontend/src/i18n/lang/en.json | 10 ++- frontend/src/router/index.ts | 5 ++ frontend/src/views/user/Settings.vue | 4 + frontend/src/views/user/settings/AtomFeed.vue | 75 +++++++++++++++++++ 6 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 frontend/src/views/user/settings/AtomFeed.vue diff --git a/frontend/src/components/misc/Icon.ts b/frontend/src/components/misc/Icon.ts index 558daeff5..4eda41616 100644 --- a/frontend/src/components/misc/Icon.ts +++ b/frontend/src/components/misc/Icon.ts @@ -58,6 +58,7 @@ import { faPlay, faPlus, faPowerOff, + faRss, faSearch, faShareAlt, faSignOutAlt, @@ -168,6 +169,7 @@ library.add(faPercent) library.add(faPlay) library.add(faPlus) library.add(faPowerOff) +library.add(faRss) library.add(faSave) library.add(faSearch) library.add(faShareAlt) diff --git a/frontend/src/components/notifications/Notifications.vue b/frontend/src/components/notifications/Notifications.vue index c8e702142..cec662781 100644 --- a/frontend/src/components/notifications/Notifications.vue +++ b/frontend/src/components/notifications/Notifications.vue @@ -24,7 +24,18 @@ ref="popup" class="notifications-list" > - {{ $t('notification.title') }} +
+ {{ $t('notification.title') }} + + {{ $t('notification.subscribeFeed') }} + + +
import('@/views/user/settings/DataExport.vue'), }, + { + path: '/user/settings/feeds', + name: 'user.settings.feeds', + component: () => import('@/views/user/settings/AtomFeed.vue'), + }, { path: '/user/settings/deletion', name: 'user.settings.deletion', diff --git a/frontend/src/views/user/Settings.vue b/frontend/src/views/user/Settings.vue index aa1b92350..4879cf617 100644 --- a/frontend/src/views/user/Settings.vue +++ b/frontend/src/views/user/Settings.vue @@ -67,6 +67,10 @@ const navigationItems = computed(() => { routeName: 'user.settings.caldav', condition: caldavEnabled.value, }, + { + title: t('user.settings.feeds.title'), + routeName: 'user.settings.feeds', + }, { title: t('user.settings.apiTokens.title'), routeName: 'user.settings.apiTokens', diff --git a/frontend/src/views/user/settings/AtomFeed.vue b/frontend/src/views/user/settings/AtomFeed.vue new file mode 100644 index 000000000..0a1e29f29 --- /dev/null +++ b/frontend/src/views/user/settings/AtomFeed.vue @@ -0,0 +1,75 @@ + + + From d4e186a02406396eec48a569b823c9c372422032 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 May 2026 09:25:44 +0000 Subject: [PATCH 052/313] chore(deps): update dependency caniuse-lite to v1.0.30001793 --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index fc79cda7d..0f6ea8f8a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -125,7 +125,7 @@ "@vueuse/shared": "14.3.0", "autoprefixer": "10.5.0", "browserslist": "4.28.2", - "caniuse-lite": "1.0.30001792", + "caniuse-lite": "1.0.30001793", "csstype": "3.2.3", "esbuild": "0.28.0", "eslint": "9.39.4", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f681726b6..f7c45e291 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -233,8 +233,8 @@ importers: specifier: 4.28.2 version: 4.28.2 caniuse-lite: - specifier: 1.0.30001792 - version: 1.0.30001792 + specifier: 1.0.30001793 + version: 1.0.30001793 csstype: specifier: 3.2.3 version: 3.2.3 @@ -3482,8 +3482,8 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001792: - resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} capture-website@4.2.0: resolution: {integrity: sha512-EmkSn36CXTC8tUsS6aNmvvsdpfVTYYkuRp7U5bV9gcJwcDbqqA5c0Op/iskYPKtDdOkuVp61mjn/LLywX0h7cw==} @@ -10192,7 +10192,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.14): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001792 + caniuse-lite: 1.0.30001793 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.14 @@ -10321,7 +10321,7 @@ snapshots: browserslist@4.28.2: dependencies: baseline-browser-mapping: 2.10.12 - caniuse-lite: 1.0.30001792 + caniuse-lite: 1.0.30001793 electron-to-chromium: 1.5.329 node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -10380,7 +10380,7 @@ snapshots: camelcase@8.0.0: {} - caniuse-lite@1.0.30001792: {} + caniuse-lite@1.0.30001793: {} capture-website@4.2.0(typescript@5.9.3): dependencies: From 4a16df8af1a832caf3f35e99771e66c5a0bf0c80 Mon Sep 17 00:00:00 2001 From: bradmartin333 Date: Fri, 15 May 2026 17:59:18 -0600 Subject: [PATCH 053/313] fix(frontend): ensure text color inherits in filter autocomplete component --- frontend/src/components/input/filter/FilterCommandsList.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/input/filter/FilterCommandsList.vue b/frontend/src/components/input/filter/FilterCommandsList.vue index fe1348bd4..34c92887b 100644 --- a/frontend/src/components/input/filter/FilterCommandsList.vue +++ b/frontend/src/components/input/filter/FilterCommandsList.vue @@ -135,6 +135,7 @@ defineExpose({ inline-size: 100%; text-align: start; background: transparent; + color: inherit; border-radius: $radius; border: 0; padding: 0.375rem 0.5rem; From dbccbd64ef76a1508a63a5a3fd1e4edadafeb251 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 18 May 2026 13:23:43 +0200 Subject: [PATCH 054/313] fix(relations): correctly position quick add magic hint (#2766) --- .../src/components/tasks/partials/RelatedTasks.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/tasks/partials/RelatedTasks.vue b/frontend/src/components/tasks/partials/RelatedTasks.vue index 3f9eef36b..8e81a2083 100644 --- a/frontend/src/components/tasks/partials/RelatedTasks.vue +++ b/frontend/src/components/tasks/partials/RelatedTasks.vue @@ -77,7 +77,7 @@ - +
component is too much resulting in a From 52f3dd6806299276c128a93155c5e03b37c07035 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Mon, 18 May 2026 17:39:13 +0000 Subject: [PATCH 055/313] fix(ci): commit newly added Crowdin translation files The Crowdin sync workflow used `git diff --quiet` and `git commit -am`, both of which only consider tracked files. New language files downloaded by Crowdin (e.g. el-GR, th-TH) were therefore left untracked and silently dropped on each run. Switch the change check to `git status --porcelain` scoped to the translation directories and stage them explicitly before committing so new locales are included. --- .github/workflows/crowdin.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index b364de00d..93d5bbf71 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -41,7 +41,7 @@ jobs: - name: Check for changes id: check_changes run: | - if git diff --quiet; then + if [ -z "$(git status --porcelain pkg/i18n/lang frontend/src/i18n/lang)" ]; then echo "changes_exist=0" >> "$GITHUB_OUTPUT" else echo "changes_exist=1" >> "$GITHUB_OUTPUT" @@ -51,7 +51,8 @@ jobs: run: | git config --local user.email "bot@vikunja.io" git config --local user.name "Frederick [Bot]" - git commit -am "chore(i18n): update translations via Crowdin" + git add pkg/i18n/lang frontend/src/i18n/lang + git commit -m "chore(i18n): update translations via Crowdin" - name: Push changes if: steps.check_changes.outputs.changes_exist != '0' uses: ad-m/github-push-action@master From 941f6bb1bef23da0ce65f053c28c1ba3ca054599 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Mon, 18 May 2026 15:22:27 +0000 Subject: [PATCH 056/313] fix(tooltip): show tooltips in top layer when inside modal dialog Tooltips on relative dates (and other content) were invisible when a task was opened in the modal. The modal uses opened via showModal(), which places it in the browser's top layer. floating-vue teleports tooltips to by default, so they were rendered *below* the dialog backdrop and hidden behind it. Wrap the v-tooltip directive to detect the nearest ancestor of the target and use it as the tooltip's container, keeping the tooltip in the same top-layer context as the modal it belongs to. Tooltips outside any dialog still teleport to as before. --- frontend/src/directives/tooltip.ts | 49 ++++++++++++++++++++++++++++++ frontend/src/main.ts | 4 +-- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 frontend/src/directives/tooltip.ts diff --git a/frontend/src/directives/tooltip.ts b/frontend/src/directives/tooltip.ts new file mode 100644 index 000000000..4c76d6ed6 --- /dev/null +++ b/frontend/src/directives/tooltip.ts @@ -0,0 +1,49 @@ +import type {Directive, DirectiveBinding} from 'vue' +import {vTooltip} from 'floating-vue' + +// When a tooltip target lives inside a opened via showModal(), the +// dialog is in the browser's top layer. floating-vue teleports tooltips to +// by default, so they render *below* the dialog's ::backdrop and are +// not visible. Teleporting them into the dialog keeps them in the top layer. +function buildBinding(el: Element, binding: DirectiveBinding): DirectiveBinding { + const dialog = el.closest('dialog') + if (!dialog) { + return binding + } + + const value = binding.value + let normalized: Record + if (typeof value === 'string') { + normalized = {content: value} + } else if (value && typeof value === 'object') { + normalized = {...value as Record} + } else { + return binding + } + + if (normalized.container === undefined) { + normalized.container = dialog + } + + return {...binding, value: normalized} +} + +// Bind via `mounted` rather than `beforeMount` so the element is already +// attached to the DOM — otherwise `el.closest('dialog')` cannot find the +// dialog ancestor. +const tooltip: Directive = { + mounted(el, binding) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(vTooltip as any).beforeMount(el, buildBinding(el, binding)) + }, + updated(el, binding) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(vTooltip as any).updated(el, buildBinding(el, binding)) + }, + beforeUnmount(el) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(vTooltip as any).beforeUnmount(el) + }, +} + +export default tooltip diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 1a81de2a2..6f64e8d8c 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -38,7 +38,7 @@ if (window.API_URL.endsWith('/')) { // directives import focus from '@/directives/focus' -import {vTooltip} from 'floating-vue' +import tooltip from '@/directives/tooltip' import 'floating-vue/dist/style.css' import shortcut from '@/directives/shortcut' import testid from '@/directives/testid' @@ -66,7 +66,7 @@ setLanguage(browserLanguage).then(() => { app.use(Notifications) app.directive('focus', focus) - app.directive('tooltip', vTooltip) + app.directive('tooltip', tooltip) app.directive('shortcut', shortcut) app.directive('cy', testid) From f349b6360e25829f28a28db92bbd682e8c9077e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 17:38:02 +0000 Subject: [PATCH 057/313] chore(deps): bump brace-expansion from 5.0.5 to 5.0.6 in /frontend Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.5 to 5.0.6. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.5...v5.0.6) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 5.0.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f7c45e291..e6ef1c0bf 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -3417,8 +3417,8 @@ packages: resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} engines: {node: '>=18'} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -10310,7 +10310,7 @@ snapshots: widest-line: 5.0.0 wrap-ansi: 9.0.2 - brace-expansion@5.0.5: + brace-expansion@5.0.6: dependencies: balanced-match: 4.0.3 @@ -12145,7 +12145,7 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.6 minimist-options@4.1.0: dependencies: From ad457488fdb3a134f3efabdd3edc05007002e2a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 12:08:10 +0000 Subject: [PATCH 058/313] chore(deps): update dependency vue-tsc to v3.3.0 --- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 0f6ea8f8a..8929a1482 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -154,7 +154,7 @@ "vite-plugin-vue-devtools": "8.1.2", "vite-svg-loader": "5.1.1", "vitest": "4.1.6", - "vue-tsc": "3.2.9", + "vue-tsc": "3.3.0", "wait-on": "9.0.10", "workbox-cli": "7.4.1", "ws": "8.20.1" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index e6ef1c0bf..2ddc24715 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -320,8 +320,8 @@ importers: specifier: 4.1.6 version: 4.1.6(@types/node@24.12.4)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: - specifier: 3.2.9 - version: 3.2.9(typescript@5.9.3) + specifier: 3.3.0 + version: 3.3.0(typescript@5.9.3) wait-on: specifier: 9.0.10 version: 9.0.10 @@ -3140,8 +3140,8 @@ packages: typescript: optional: true - '@vue/language-core@3.2.9': - resolution: {integrity: sha512-ie0ojt/0fU/GfIogh+zgHbaYRPlt9S+cLOxcWwF7nTSFh897BVgnFKL2byT4kpp1mlqYWZ2psGwSniyE2xsxYw==} + '@vue/language-core@3.3.0': + resolution: {integrity: sha512-EyUxq1b8Yoxk6hQ6X33BIRnfFLb9Rbm9w/8G8y6uMxlQu7CW7yy9JS/z54xSpIvBvVWX6Lt5v1aBGwmrqD4aJw==} '@vue/reactivity@3.5.27': resolution: {integrity: sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==} @@ -6861,8 +6861,8 @@ packages: peerDependencies: vue: ^3.5.0 - vue-tsc@3.2.9: - resolution: {integrity: sha512-qm8/nbo+9eZc1SCndm9wT+gq23pM+wRIdHY0wjm83B3lIginHTwcdrLUyTrKjDWXbMVNjKegNrnymhpdqnCL3A==} + vue-tsc@3.3.0: + resolution: {integrity: sha512-kY8RcoTOENASi0P1GLPvJgA2+hoGF+t8We1UGgmnAb1r/GjTUMSE3zz+WGfjPORZNnBHdAt67sVPhBLXWunkeg==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -10019,7 +10019,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vue/language-core@3.2.9': + '@vue/language-core@3.3.0': dependencies: '@volar/language-core': 2.4.28 '@vue/compiler-dom': 3.5.27 @@ -14132,10 +14132,10 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.27(typescript@5.9.3) - vue-tsc@3.2.9(typescript@5.9.3): + vue-tsc@3.3.0(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.28 - '@vue/language-core': 3.2.9 + '@vue/language-core': 3.3.0 typescript: 5.9.3 vue@3.5.27(typescript@5.9.3): From faeeebe66169dde08628f595fe79591174613302 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 18:39:17 +0000 Subject: [PATCH 059/313] chore(deps): update dev-dependencies to v8.59.4 --- frontend/package.json | 4 +- frontend/pnpm-lock.yaml | 150 ++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 8929a1482..5bc5aaf52 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -116,8 +116,8 @@ "@types/node": "24.12.4", "@types/sortablejs": "1.15.9", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.59.3", - "@typescript-eslint/parser": "8.59.3", + "@typescript-eslint/eslint-plugin": "8.59.4", + "@typescript-eslint/parser": "8.59.4", "@vitejs/plugin-vue": "6.0.7", "@vue/eslint-config-typescript": "14.7.0", "@vue/test-utils": "2.4.10", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 2ddc24715..24bf97e1d 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -206,17 +206,17 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.59.3 - version: 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.4 + version: 8.59.4(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.59.3 - version: 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.59.4 + version: 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.7 version: 6.0.7(vite@7.3.3(@types/node@24.12.4)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': specifier: 2.4.10 version: 2.4.10(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) @@ -249,7 +249,7 @@ importers: version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: specifier: 10.9.1 - version: 10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + version: 10.9.1(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: specifier: 20.9.0 version: 20.9.0 @@ -2872,11 +2872,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.59.3': - resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==} + '@typescript-eslint/eslint-plugin@8.59.4': + resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.3 + '@typescript-eslint/parser': ^8.59.4 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -2887,8 +2887,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.59.3': - resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==} + '@typescript-eslint/parser@8.59.4': + resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2906,8 +2906,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.3': - resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==} + '@typescript-eslint/project-service@8.59.4': + resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2920,8 +2920,8 @@ packages: resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.59.3': - resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==} + '@typescript-eslint/scope-manager@8.59.4': + resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.56.0': @@ -2936,14 +2936,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.2': - resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} + '@typescript-eslint/tsconfig-utils@8.59.3': + resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.59.3': - resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} + '@typescript-eslint/tsconfig-utils@8.59.4': + resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -2955,8 +2955,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.59.3': - resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==} + '@typescript-eslint/type-utils@8.59.4': + resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2970,14 +2970,14 @@ packages: resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.2': - resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.59.3': resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.4': + resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.0': resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2990,8 +2990,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/typescript-estree@8.59.3': - resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==} + '@typescript-eslint/typescript-estree@8.59.4': + resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -3010,8 +3010,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.3': - resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==} + '@typescript-eslint/utils@8.59.4': + resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3025,8 +3025,8 @@ packages: resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.59.3': - resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==} + '@typescript-eslint/visitor-keys@8.59.4': + resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -9627,14 +9627,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.59.3 - '@typescript-eslint/type-utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.3 + '@typescript-eslint/parser': 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/type-utils': 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.4 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9655,12 +9655,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.3 - '@typescript-eslint/types': 8.59.3 - '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.59.3 + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.4 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 @@ -9669,8 +9669,8 @@ snapshots: '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9678,17 +9678,17 @@ snapshots: '@typescript-eslint/project-service@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.3(typescript@5.9.3)': + '@typescript-eslint/project-service@8.59.4(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) - '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: @@ -9704,10 +9704,10 @@ snapshots: '@typescript-eslint/types': 8.58.0 '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/scope-manager@8.59.3': + '@typescript-eslint/scope-manager@8.59.4': dependencies: - '@typescript-eslint/types': 8.59.3 - '@typescript-eslint/visitor-keys': 8.59.3 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: @@ -9717,11 +9717,11 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.4(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -9737,11 +9737,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.59.3 - '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) @@ -9753,10 +9753,10 @@ snapshots: '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/types@8.59.2': {} - '@typescript-eslint/types@8.59.3': {} + '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) @@ -9787,12 +9787,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.59.3(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.4(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.59.3(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) - '@typescript-eslint/types': 8.59.3 - '@typescript-eslint/visitor-keys': 8.59.3 + '@typescript-eslint/project-service': 8.59.4(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.3 @@ -9824,12 +9824,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.59.3 - '@typescript-eslint/types': 8.59.3 - '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9845,9 +9845,9 @@ snapshots: '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.0 - '@typescript-eslint/visitor-keys@8.59.3': + '@typescript-eslint/visitor-keys@8.59.4': dependencies: - '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/types': 8.59.4 eslint-visitor-keys: 5.0.0 '@ungap/structured-clone@1.3.0': {} @@ -10006,11 +10006,11 @@ snapshots: '@vue/devtools-shared@8.1.2': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) - eslint-plugin-vue: 10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) + eslint-plugin-vue: 10.9.1(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) @@ -10984,7 +10984,7 @@ snapshots: module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): + eslint-plugin-vue@10.9.1(@typescript-eslint/parser@8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) eslint: 9.39.4(jiti@2.6.1) @@ -10995,7 +10995,7 @@ snapshots: vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.4(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: From fee2d2ea58b9452ee8323f215de8d17366687d06 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Mon, 18 May 2026 18:15:20 +0000 Subject: [PATCH 060/313] fix(notifications): skip logo attachment for conversational mails The conversational mail template does not reference cid:logo.png, but RenderMail still attached the embedded logo to every outgoing mail. That left an orphan inline part that some clients render as a stray attachment. Only embed logo.png when the formal template is in use. --- pkg/notifications/mail_render.go | 7 +++++-- pkg/notifications/mail_test.go | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/notifications/mail_render.go b/pkg/notifications/mail_render.go index 67b254d35..292927c80 100644 --- a/pkg/notifications/mail_render.go +++ b/pkg/notifications/mail_render.go @@ -407,9 +407,12 @@ func RenderMail(m *Mail, lang string) (mailOpts *mail.Opts, err error) { HTMLMessage: htmlContent.String(), Boundary: boundary, ThreadID: m.threadID, - EmbedFS: map[string]*embed.FS{ + } + + if !m.conversational { + mailOpts.EmbedFS = map[string]*embed.FS{ "logo.png": &logo, - }, + } } return mailOpts, nil diff --git a/pkg/notifications/mail_test.go b/pkg/notifications/mail_test.go index 125a13cd0..fca5c6447 100644 --- a/pkg/notifications/mail_test.go +++ b/pkg/notifications/mail_test.go @@ -533,6 +533,7 @@ func TestConversationalMail(t *testing.T) { // Should NOT have logo (completely removed) assert.NotContains(t, mailopts.HTMLMessage, "logo.png") assert.NotContains(t, mailopts.HTMLMessage, "Vikunja") + assert.NotContains(t, mailopts.EmbedFS, "logo.png") // Should have inline action link with arrow assert.Contains(t, mailopts.HTMLMessage, "View Task →") @@ -571,6 +572,7 @@ func TestConversationalMail(t *testing.T) { // Should HAVE logo in formal emails assert.Contains(t, mailopts.HTMLMessage, "logo.png") assert.Contains(t, mailopts.HTMLMessage, "Vikunja") + assert.Contains(t, mailopts.EmbedFS, "logo.png") // Should have formal button styling assert.Contains(t, mailopts.HTMLMessage, "background-color: #1973ff") From a79517a79a262831d9ab0751100c2b1e52f5320c Mon Sep 17 00:00:00 2001 From: Tink bot Date: Mon, 18 May 2026 18:59:35 +0000 Subject: [PATCH 061/313] fix(frontend): prevent avatar layout shift while loading The .avatar img in User.vue relied solely on the width/height HTML attributes for sizing. Those are presentational hints with zero CSS specificity, so Bulma's global reset (img { height: auto; max-width: 100% }) overrode them. While avatarSrc was still resolving (initial src=""), the browser had no intrinsic dimensions to compute the auto height from and fell back to the broken-image box (~96px in Chrome), then snapped to the real size once the blob URL loaded. Set inline-size/block-size explicitly via a CSS custom property bound to the avatarSize prop so the rendered size is locked regardless of load state or the Bulma reset. --- frontend/src/components/misc/User.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/misc/User.vue b/frontend/src/components/misc/User.vue index b7348b1a5..bc7fe137a 100644 --- a/frontend/src/components/misc/User.vue +++ b/frontend/src/components/misc/User.vue @@ -2,6 +2,7 @@
[props.user, props.avatarSize], loadAvatar, { immediate: true }) } .avatar { + inline-size: var(--avatar-size); + block-size: var(--avatar-size); border-radius: 100%; vertical-align: middle; } From c761ab9761eb5f20b2c56c50297548f83e726e11 Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Tue, 19 May 2026 02:26:35 +0000 Subject: [PATCH 062/313] chore(i18n): update translations via Crowdin --- frontend/src/i18n/lang/de-DE.json | 10 +- frontend/src/i18n/lang/de-swiss.json | 10 +- frontend/src/i18n/lang/el-GR.json | 88 +++++++++++++ frontend/src/i18n/lang/fa-IR.json | 1 + frontend/src/i18n/lang/th-TH.json | 1 + pkg/i18n/lang/de-DE.json | 5 + pkg/i18n/lang/de-swiss.json | 5 + pkg/i18n/lang/el-GR.json | 182 +++++++++++++++++++++++++++ pkg/i18n/lang/fa-IR.json | 1 + pkg/i18n/lang/th-TH.json | 1 + 10 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 frontend/src/i18n/lang/el-GR.json create mode 100644 frontend/src/i18n/lang/fa-IR.json create mode 100644 frontend/src/i18n/lang/th-TH.json create mode 100644 pkg/i18n/lang/el-GR.json create mode 100644 pkg/i18n/lang/fa-IR.json create mode 100644 pkg/i18n/lang/th-TH.json diff --git a/frontend/src/i18n/lang/de-DE.json b/frontend/src/i18n/lang/de-DE.json index 4d88eaa68..02958a0ec 100644 --- a/frontend/src/i18n/lang/de-DE.json +++ b/frontend/src/i18n/lang/de-DE.json @@ -219,6 +219,13 @@ "usernameIs": "Dein Anmeldename für CalDAV lautet: {0}", "apiTokenHint": "Du kannst auch ein API-Token mit CalDAV-Berechtigung verwenden. Erstelle eins unter {link}." }, + "feeds": { + "title": "Atom-Feed", + "howTo": "Du kannst deine Vikunja-Benachrichtigungen von jedem Atom-kompatiblen Feed-Reader abonnieren. Benutze die folgende URL:", + "usernameIs": "Dein Anmeldename für das Feed lautet: {0}", + "apiTokenHint": "Authentifiziere dich mit einem API-Token mit der {scope} Berechtigung. Erstellen eins unter {link}.", + "tokenTitle": "Atom-Feed" + }, "avatar": { "title": "Avatar", "initials": "Initialen", @@ -1323,7 +1330,8 @@ "none": "Du hast keine Benachrichtigungen. Einen schönen Tag noch!", "explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden.", "markAllRead": "Alle Benachrichtigungen als gelesen markieren", - "markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert." + "markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert.", + "subscribeFeed": "Benachrichtigungen über Atom-Feed abonnieren" }, "quickActions": { "notLoggedIn": "Bitte melde dich zuerst im Hauptfenster von Vikunja an.", diff --git a/frontend/src/i18n/lang/de-swiss.json b/frontend/src/i18n/lang/de-swiss.json index c20af1643..2f53ebd43 100644 --- a/frontend/src/i18n/lang/de-swiss.json +++ b/frontend/src/i18n/lang/de-swiss.json @@ -219,6 +219,13 @@ "usernameIs": "Dein Anmeldename für CalDAV lautet: {0}", "apiTokenHint": "Du kannst auch ein API-Token mit CalDAV-Berechtigung verwenden. Erstelle eins unter {link}." }, + "feeds": { + "title": "Atom-Feed", + "howTo": "Du kannst deine Vikunja-Benachrichtigungen von jedem Atom-kompatiblen Feed-Reader abonnieren. Benutze die folgende URL:", + "usernameIs": "Dein Anmeldename für das Feed lautet: {0}", + "apiTokenHint": "Authentifiziere dich mit einem API-Token mit der {scope} Berechtigung. Erstellen eins unter {link}.", + "tokenTitle": "Atom-Feed" + }, "avatar": { "title": "Herr Der Elemente", "initials": "Initialä", @@ -1323,7 +1330,8 @@ "none": "Du hesch kei neui Benachrichtunge. Heb e schös Tägli!", "explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden.", "markAllRead": "Alle Benachrichtigungen als gelesen markieren", - "markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert." + "markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert.", + "subscribeFeed": "Benachrichtigungen über Atom-Feed abonnieren" }, "quickActions": { "notLoggedIn": "Bitte melde dich zuerst im Hauptfenster von Vikunja an.", diff --git a/frontend/src/i18n/lang/el-GR.json b/frontend/src/i18n/lang/el-GR.json new file mode 100644 index 000000000..5083fb8d1 --- /dev/null +++ b/frontend/src/i18n/lang/el-GR.json @@ -0,0 +1,88 @@ +{ + "home": { + "welcomeNight": "Καληνύχτα {username}!", + "welcomeNightOwl": "Γεια σου νυχτερινή κουκουβάγια {username}", + "welcomeNightBurning": "Κάνουμε υπερωρίες {username};", + "welcomeDayKeepGoing": "Συνέχισε, {username}" + }, + "user": { + "auth": { + "openIdTotpRequired": "Ο λογαριασμός σας απαιτεί ταυτοποίηση δύο παραγόντων. Εισαγάγετε τον κωδικό σας μίας χρήσης και κάνετε είσοδο εκ νέου.", + "desktopWaitingForAuth": "Αναμονή για ταυτοποίηση…", + "desktopOAuthError": "Η ταυτοποίηση απέτυχε: {error}" + }, + "settings": { + "bots": { + "description": "Οι χρήστες bot είναι μόνο API-χρήστες που εσείς κατέχετε. Μπορούν να προστεθούν σε έργα, ανατεθειμένες εργασίες και ταυτοποιούνται με τεκμήρια API. Δεν μπορούν να συνδεθούν διαδραστικά." + }, + "totp": { + "title": "Ταυτοποίηση Δύο Παραγόντων", + "confirmNotice": "Μετά την ενεργοποίηση της ταυτοποίησης δύο παραγόντων, θα αποσυνδεθείτε από όλες τις συνεδρίες και θα πρέπει να κάνετε είσοδο εκ νέου.", + "setupSuccess": "Έχετε παραμετροποιήσει με επιτυχία τον έλεγχο ταυτοποίησης δύο παραγόντων!", + "disable": "Απενεργοποίηση ταυτοποίησης δύο παραγόντων", + "confirmSuccess": "Έχετε ενεργοποιήσει με επιτυχία τον έλεγχο ταυτοποίησης δύο παραγόντων!", + "disableSuccess": "Ο έλεγχος ταυτοποίησης δύο παραγόντων απενεργοποιήθηκε με επιτυχία." + }, + "caldav": { + "tokensHowTo": "Για ταυτοποίηση CalDAV μπορείτε να χρησιμοποιήσετε είτε τον κανονικό κωδικό πρόσβασής σας είτε ένα τεκμήριο CalDAV." + }, + "feeds": { + "apiTokenHint": "Ταυτοποιηθείτε με τεκμήριο API που έχει την άδεια {scope}. Δημιουργήστε ένα στο {link}." + } + } + }, + "project": { + "webhooks": { + "basicauthuser": "Χρήστης για Βασική Ταυτοποίηση", + "basicauthpassword": "Κωδικός πρόσβασης για Βασική Ταυτοποίηση", + "basicauthlink": "Χρήση της Βασικής Ταυτοποίησης;" + }, + "views": { + "deleteText": "Είστε σίγουροι ότι θέλετε να αφαιρέσετε την προβολή; Δε θα είναι πλέον δυνατό να τη χρησιμοποιήσετε για να δείτε εργασίες σε αυτό το έργο. Αυτή η ενέργεια δε θα διαγράψει καμία εργασία. Αυτή η ενέργεια είναι μη αναιρέσιμη!" + } + }, + "filters": { + "fromView": "Η τρέχουσα προβολή έχει επίσης ένα σύνολο φίλτρων:", + "fromViewBoth": "Θα χρησιμοποιηθεί σε συνδυασμό με αυτό που εισαγάγετε εδώ.", + "create": { + "description": "Ένα αποθηκευμένο φίλτρο είναι ένα εικονικό έργο το οποίο δημιουργείται από ένα σύνολο φίλτρων κάθε φορά που το προσπελαύνει κανείς." + }, + "query": { + "help": { + "canUseDatemath": "Μπορείτε να χρησιμοποιήσετε μαθηματικά στις ημερομηνίες για να ορίσετε σχετικές ημερομηνίες. Κάντε κλικ στην τιμή της ημερομηνίας σε ένα ερώτημα για να μάθετε περισσότερα.", + "fields": { + "done": "Αν η εργασία έχει ολοκληρωθεί ή όχι", + "reminders": "Οι υπενθυμίσεις της εργασίας ως πεδίο ημερομηνίας, θα επιστρέψουν όλες τις εργασίες με τουλάχιστον μία υπενθύμιση που ταιριάζει με το ερώτημα", + "created": "Η ώρα και ημερομηνία που δημιουργήθηκε η εργασία", + "updated": "Η ώρα και η ημερομηνία τελευταίας τροποποίησης μιας εργασίας" + }, + "operators": { + "intro": "Οι διαθέσιμοι τελεστές για το φιλτράρισμα περιλαμβάνουν:", + "in": "Ταιριάζει με οποιαδήποτε τιμή από μια λίστα τιμών χωρισμένες με κόμμα", + "notIn": "Ταιριάζει με οποιαδήποτε τιμή που δεν υπάρχει σε μια λίστα τιμών χωρισμένες με κόμμα" + }, + "logicalOperators": { + "intro": "Για να συνδυάσετε πολλαπλές συνθήκες, μπορείτε να χρησιμοποιήσετε τους ακόλουθους λογικούς τελεστές:", + "and": "Τελεστής AND, ταιριάζει όλες τις συνθήκες που είναι αληθείς", + "or": "Τελεστής OR, ταιριάζει αν κάποια από τις συνθήκες είναι αληθής", + "parentheses": "Παρενθέσεις για ομαδοποίηση συνθηκών" + }, + "examples": { + "intro": "Παρακάτω υπάρχουν ορισμένα παραδείγματα ερωτημάτων φιλτραρίσματος:", + "priorityEqual": "Ταιριάζει με εργασίες με προτεραιτότητα επιπέδου 4", + "undoneHighPriority": "Ταιριάζει με μη ολοκληρωμένες εργασίες με προτεραιότητα επιπέδου 3 ή μεγαλύτερο", + "assigneesIn": "Ταιριάζει με εργασίες που έχουν ανατεθεί είτε στο χρήστη \"user1\" ή στον \"user2\"" + } + } + } + }, + "sorting": { + "description": "Επιλέξτε πως ταξινομούνται οι εργασίες σε αυτή τη λίστα. Κατά τη χειροκίνητη ταξινόμηση, μπορείτε να σύρετε και να αφήσετε εργασίες για να τις αλλάξετε τη σειρά." + }, + "migrate": { + "description": "Κάντε κλικ στο λογότυπο μιας από τις παρακάτω υπηρεσίες τρίτων για να ξεκινήσετε.", + "descriptionDo": "Το Vikunja θα εισαγάγει όλες τις λίστες, εργασίες, σημειώσεις, υπενθυμίσεις και αρχεία που έχετε πρόσβαση.", + "authorize": "Για να επιτρέψετε στο Vikunja να προσπελάσει το {name} Λογαριασμό σας, κάντε κλικ στο παρακάτω πλήκτρο.", + "alreadyMigrated1": "Φαίνεται ότι έχετε ήδη εισαγάγει τα στοιχεία σας από το {name} στο {date}." + } +} \ No newline at end of file diff --git a/frontend/src/i18n/lang/fa-IR.json b/frontend/src/i18n/lang/fa-IR.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/frontend/src/i18n/lang/fa-IR.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/frontend/src/i18n/lang/th-TH.json b/frontend/src/i18n/lang/th-TH.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/frontend/src/i18n/lang/th-TH.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/pkg/i18n/lang/de-DE.json b/pkg/i18n/lang/de-DE.json index 64762d377..c446214de 100644 --- a/pkg/i18n/lang/de-DE.json +++ b/pkg/i18n/lang/de-DE.json @@ -173,5 +173,10 @@ "since_hours": "einer Stunde|%[1]d Stunden", "since_minutes": "einer Minute|%[1]d Minuten", "list_last_separator": "und" + }, + "feeds": { + "notifications": { + "title": "Vikunja Benachrichtigungen für %[1]s" + } } } \ No newline at end of file diff --git a/pkg/i18n/lang/de-swiss.json b/pkg/i18n/lang/de-swiss.json index 64762d377..c446214de 100644 --- a/pkg/i18n/lang/de-swiss.json +++ b/pkg/i18n/lang/de-swiss.json @@ -173,5 +173,10 @@ "since_hours": "einer Stunde|%[1]d Stunden", "since_minutes": "einer Minute|%[1]d Minuten", "list_last_separator": "und" + }, + "feeds": { + "notifications": { + "title": "Vikunja Benachrichtigungen für %[1]s" + } } } \ No newline at end of file diff --git a/pkg/i18n/lang/el-GR.json b/pkg/i18n/lang/el-GR.json new file mode 100644 index 000000000..d14c2664d --- /dev/null +++ b/pkg/i18n/lang/el-GR.json @@ -0,0 +1,182 @@ +{ + "notifications": { + "greeting": "Γεια σου %[1]s,", + "email_confirm": { + "subject": "%[1]s, παρακαλώ επιβεβαίωσε τη διεύθυνση email σου στο Vikunja", + "subject_new": "%[1]s + Vikunja = <3", + "welcome": "Καλωσορίσατε στο Vikunja!", + "confirm": "Για να επιβεβαιώσεις τη διεύθυνση email σου, κάνε κλικ στον παρακάτω σύνδεσμο:" + }, + "password": { + "changed": { + "subject": "Ο κωδικός σου πρόσβασης στο Vikunja άλλαξε", + "success": "Ο κωδικός πρόσβασης του λογαριασμού σου άλλαξε με επιτυχία.", + "warning": "Αν δεν ήσουν εσύ, αυτό θα μπορούσε να σημαίνει ότι κάποιος παραβίασε το λογαριασμό σου. Σε αυτή την περίπτωση επικοινώνησε με το διαχειριστή του διακομιστή σου." + }, + "reset": { + "subject": "Επανάφερε τον κωδικό σου στο Vikunja", + "instructions": "Για να επαναφέρεις τον κωδικό σου, πάτησε στον παρακάτω σύνδεσμο:", + "valid_duration": "Ο σύνδεσμος θα ισχύει για 24 ώρες." + } + }, + "totp": { + "invalid": { + "subject": "Κάποιος μόλις προσπάθησε να εισέλθει στο λογαριασμό σου στο Vikunja, αλλά απέτυχε", + "message": "Κάποιος μόλις προσπάθησε να συνδεθεί στο λογαριασμό σου με το σωστό όνομα χρήστη και κωδικό πρόσβασης, αλλά με λάθος κωδικό TOTP.", + "warning": "**Εάν δεν ήσουν εσύ, κάποιος άλλος γνωρίζει τον κωδικό σου πρόσβασης. Θα πρέπει να ορίσεις ένα νέο αμέσως!**" + }, + "account_locked": { + "subject": "Έχουμε απενεργοποιήσει το λογαριασμό σου στο Vikunja", + "message": "Κάποιος προσπάθησε να συνδεθεί με τα διαπιστευτήριά σας αλλά απέτυχε να δώσει έγκυρο κωδικό πρόσβασης TOTP.", + "disabled": "Μετά από 10 αποτυχημένες προσπάθειες, έχουμε απενεργοποιήσει το λογαριασμό σας και επαναφέραμε τον κωδικό σας πρόσβασης. Για να ορίσετε ένα νέο, ακολουθήστε τις οδηγίες στο email επαναφοράς που μόλις σας στείλαμε.", + "reset_instructions": "Εάν δε λάβατε ένα email με οδηγίες επαναφοράς, μπορείτε πάντα να ζητήσετε ένα νέο στο [%[1]s](%[2]s)." + } + }, + "login": { + "failed": { + "subject": "Κάποιος μόλις προσπάθησε να εισέλθει στο λογαριασμό σας στο Vikunja, αλλά απέτυχε να δώσει σωστό κωδικό πρόσβασης", + "message": "Κάποιος μόλις προσπάθησε να συνδεθεί στο λογαριασμό σας με λάθος κωδικό πρόσβασης τρεις φορές συνεχόμενα.", + "warning": "Αν δεν ήσασταν εσείς, θα μπορούσε να είναι κάποιος άλλος που προσπαθεί να εισέλθει κακόβουλα στο λογαριασμό σας.", + "enhance_security": "Για να ενισχύσετε την ασφάλεια του λογαριασμού σας μπορείτε να ορίσετε έναν ισχυρότερο κωδικό πρόσβασης ή να ενεργοποιήσετε τον έλεγχο ταυτοποίησης TOTP στις ρυθμίσεις:" + } + }, + "account": { + "deletion": { + "confirm": { + "subject": "Παρακαλώ επιβεβαιώστε τη διαγραφή του λογαριασμού σας στο Vikunja", + "request": "Ζητήσατε τη διαγραφή του λογαριασμού σας. Για να επιβεβαιώσετε την ενέργεια, κάντε κλικ στον παρακάτω σύνδεσμο:", + "valid_duration": "Ο σύνδεσμος θα ισχύει για 24 ώρες.", + "schedule_info": "Μόλις επιβεβαιώσετε τη διαγραφή, θα προγραμματίσουμε τη διαγραφή του λογαριασμού σας σε τρεις ημέρες και θα σας στείλουμε ένα άλλο email μέχρι τότε.", + "consequences": "Αν προχωρήσετε με τη διαγραφή του λογαριασμού σας, θα καταργήσουμε όλα τα έργα και τις εργασίες που δημιουργήσατε. Η κυριότητα όλων όσων μοιραστήκατε με άλλο χρήστη ή ομάδα θα μεταφερθεί σε αυτούς.", + "changed_mind": "Αν δεν αιτηθήκατε τη διαγραφή ή αλλάξατε γνώμη, μπορείτε απλά να αγνοήσετε αυτό το email." + }, + "scheduled": { + "subject_days": "Ο λογαριασμός σας στο Vikunja θα διαγραφεί σε %[1]ημέρες", + "subject_tomorrow": "Ο λογαριασμός σας στο Vikunja θα διαγραφεί αύριο", + "request_reminder": "Αιτηθήκατε πρόσφατα τη διαγραφή του λογαριασμού σας στο Vikunja.", + "deletion_time_days": "Θα διαγράψουμε τον λογαριασμό σας σε %[1]s ημέρες.", + "deletion_time_tomorrow": "Θα διαγράψουμε τον λογαριασμό σας αύριο.", + "changed_mind": "Αν αλλάξατε γνώμη, απλά κάντε κλικ στον παρακάτω σύνδεσμο για να ακυρώσετε τη διαγραφή και ακολουθήστε τις οδηγίες:" + }, + "completed": { + "subject": "Ο λογαριασμός σας στο Vikunja έχει διαγραφεί", + "confirmation": "Όπως ζητήθηκε, έχουμε διαγράψει το λογαριασμό σας στο Vikunja.", + "permanent": "Η διαγραφή είναι μόνιμη. Αν δε δημιουργήσατε αντίγραφο ασφαλείας και χρειάζεστε τα δεδομένα σας αυτή τη στιγμή, επικοινωνήστε με το διαχειριστή σας." + } + } + }, + "task": { + "reminder": { + "subject": "Υπενθύμιση για \"%[1]s\" (%[2]s)", + "message": "Αυτή είναι μια φιλική υπενθύμιση για την εργασία \"%[1]s\" (%[2]s)." + }, + "comment": { + "subject": "Σχ: %[1]s (%[2]s)", + "mentioned_subject": "Ο/Η %[1]s σας ανέφερε σε ένα σχόλιο στο \"%[2]s\" (%[3]s)" + }, + "assigned": { + "subject_to_assignee": "Σας έχει ανατεθεί το \"%[1]s\" (%[2]s)", + "message_to_assignee": "Ο/Η %[1]s σας έχει αναθέσει το \"%[2]s\".", + "subject_to_others": "Το \"%[1]s\" (%[2]s) έχει ανατεθεί στον/στην %[3]s", + "message_to_others": "Ο/Η %[1]s έχει αναθέσει την εργασία στον/στην %[2]s.", + "subject_to_others_self": "Το \"%[1]s\" (%[2]s) έχει ανατεθεί από τον/την %[3]s στον εαυτό τους", + "message_to_others_self": "Ο/Η %[1]s έχει αναθέσει την εργασία στον εαυτό τους." + }, + "deleted": { + "subject": "Το \"%[1]s\" (%[2]s) έχει διαγραφεί", + "message": "Ο/Η %[1]s έχει διαγράψει την εργασία \"%[2]s\" (%[3]s)" + }, + "mentioned": { + "subject_new": "Ο/Η %[1]s σας ανέφερε σε μια νέα εργασία \"%[2]s\" (%[3]s)", + "subject": "Ο/Η %[1]s σας ανέφερε σε μια εργασία \"%[2]s\" (%[3]s)" + }, + "overdue": { + "subject": "Η εργασία \"%[1]s\" (%[2]s) είναι ληξιπρόθεσμη", + "message": "Αυτή είναι μια φιλική υπενθύμιση για την εργασία \"%[1]s\" (%[2]s) που είναι ληξιπρόθεσμη %[3]s και δεν έχει ακόμη παραδοθεί.", + "multiple_subject": "Οι εκπρόθεσμες εργασίες σας", + "multiple_message": "Έχετε τις παρακάτω εκπρόθεσμες εργασίες:", + "overdue_since": "από %[1]s", + "overdue_now": "τώρα", + "overdue": "εκπρόθεσμη %[1]s" + } + }, + "project": { + "created": "Ο/Η %[1]s δημιούργησε το έργο \"%[2]s\"" + }, + "team": { + "member_added": { + "subject": "Ο/Η %[1]s σας πρόσθεσε στην ομάδα \"%[2]s\" στο Vikunja", + "message": "Ο/Η %[1]s σας πρόσθεσε στην ομάδα %[2]s στο Vikunja." + } + }, + "data_export": { + "ready": { + "subject": "Η εξαγωγή δεδομένων σας από το Vikunja είναι έτοιμη", + "message": "Η εξαγωγή δεδομένων σας από το Vikunja είναι έτοιμη για λήψη. Κάντε κλικ στο πλήκτρο παρακάτω για τα κατεβάσετε:", + "availability": "Η λήψη θα είναι διαθέσιμη για τις επόμενες 7 ημέρες." + } + }, + "migration": { + "done": { + "subject": "Η μετάβαση από το %[1]s στο Vikunja ολοκληρώθηκε", + "imported": "Το Vikunja έχει εισαγάγει όλες τις λίστες / έργα, εργασίες, σημειώσεις, υπενθυμίσεις και αρχεία από το %[1]s που έχετε πρόσβαση.", + "have_fun": "Καλή διασκέδαση με τα νέα (παλιά) έργα σας!" + }, + "failed": { + "subject": "Η μετάβαση από το %[1]s στο Vikunja απέτυχε", + "message": "Φαίνεται ότι η μετάβαση από το %[1]s δεν πήγε όπως θέλαμε αυτή τη φορά.", + "retry": "Μην ανησυχείτε, όμως! Απλά δώστε μια ακόμη ευκαιρία ξεκινώντας με τον ίδιο τρόπο όπως και πριν. Μερικές φορές, αυτές οι αναποδιές συμβαίνουν λόγω προβλημάτων από την πλευρά του %[1]s και δοκιμάζοντας ξανά πολλές φορές λύνει το πρόβλημα.", + "error": "Εντοπίσαμε ένα μικρό σφάλμα στην πορεία: `%[2]s`.", + "report": "Παρακαλώ αφήστε μια σημείωση σχετικά με αυτό [στο φόρουμ](https://community.vikunja.io/) ή σε οποιοδήποτε από τα συνηθισμένα μέρη, έτσι ώστε να μπορούμε να ρίξουμε μια ματιά στο γιατί απέτυχε.", + "working_on_it": "Έχουμε το μήνυμα σφάλματος στο ραντάρ μας και είμαστε έτοιμοι να το τακτοποιήσουμε σύντομα." + } + }, + "api_token": { + "expiring": { + "week": { + "subject": "Το API τεκμήριό σας \"%[1]s\" λήγει σύντομα", + "message": "Το τεκμήριό σας API \"%[1]s\" θα λήξει στις %[2]s. Αν εξακολουθείτε να το χρειάζεστε, παρακαλώ δημιουργήστε ένα νέο προτού λήξει." + }, + "day": { + "subject": "Το API τεκμήριό σας \"%[1]s\" λήγει αύριο", + "message": "Το τεκμήριό σας API \"%[1]s\" θα λήξει στις %[2]s. Αν εξακολουθείτε να το χρειάζεστε, παρακαλώ δημιουργήστε ένα νέο προτού λήξει." + }, + "action": "Διαχείριση Τεκμηρίων API" + } + }, + "common": { + "have_nice_day": "Να έχεις μια όμορφη μέρα!", + "copy_url": "Αν το παραπάνω κουμπί δε λειτουργεί, αντιγράψτε το παρακάτω url και επικολλήστε το στη γραμμή διευθύνσεων του προγράμματός σας πλοήγησης:", + "actions": { + "open_task": "Άνοιγμα Εργασίας στο Vikunja", + "open_vikunja": "Άνοιγμα του Vikunja", + "open_project": "Άνοιγμα Έργου", + "open_team": "Άνοιγμα Ομάδας", + "download": "Λήψη", + "reset_password": "Επαναφορά του κωδικού σας πρόσβασης", + "go_to_settings": "Μετάβαση στις ρυθμίσεις", + "confirm_email": "Επιβεβαιώστε τη διεύθυνση email σας", + "abort_deletion": "Ματαίωση της διαγραφής", + "confirm_account_deletion": "Επιβεβαίωση της διαγραφής του λογαριασμού μου", + "change_notification_settings_link": "Μπορείτε να αλλάξετε τις ρυθμίσεις σας ειδοποίησης [here](%[1]s).", + "left_comment": "Ο/Η %[1]s άφησε ένα σχόλιο", + "mentioned_you_comment": "Ο/Η %[1]s σας ανέφερε σε ένα σχόλιο", + "mentioned_you": "Ο/Η %[1]s σας ανέφερε", + "mentioned_you_new_task": "Ο/Η %[1]s σας ανέφερε σε μια νέα εργασία" + } + } + }, + "time": { + "since_years": "ένα έτος|%[1]d έτη", + "since_weeks": "μία εβδομάδα|%[1]d εβδομάδες", + "since_days": "μία ημέρα|%[1]d ημέρες", + "since_hours": "μία ώρα|%[1]d ώρες", + "since_minutes": "ένα λεπτό|%[1]d λεπτά", + "list_last_separator": "και" + }, + "feeds": { + "notifications": { + "title": "Ειδοποιήσεις του Vikunja για %[1]s" + } + } +} \ No newline at end of file diff --git a/pkg/i18n/lang/fa-IR.json b/pkg/i18n/lang/fa-IR.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/pkg/i18n/lang/fa-IR.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/pkg/i18n/lang/th-TH.json b/pkg/i18n/lang/th-TH.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/pkg/i18n/lang/th-TH.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 21ce33f8fd1ccfb66b66fc88462f6daf7e1db878 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 10:35:43 +0200 Subject: [PATCH 063/313] feat(projects): always store identifiers as uppercase (#2775) --- pkg/db/fixtures/projects.yml | 64 ++++++++-------- pkg/migration/20260519120000.go | 108 +++++++++++++++++++++++++++ pkg/models/project.go | 5 ++ pkg/models/task_collection_test.go | 60 +++++++-------- pkg/webtests/task_collection_test.go | 30 ++++---- 5 files changed, 190 insertions(+), 77 deletions(-) create mode 100644 pkg/migration/20260519120000.go diff --git a/pkg/db/fixtures/projects.yml b/pkg/db/fixtures/projects.yml index 86d2cba24..5ab8d6536 100644 --- a/pkg/db/fixtures/projects.yml +++ b/pkg/db/fixtures/projects.yml @@ -2,7 +2,7 @@ id: 1 title: Test1 description: Lorem Ipsum - identifier: test1 + identifier: TEST1 owner_id: 1 position: 3 updated: 2018-12-02 15:13:12 @@ -11,7 +11,7 @@ id: 2 title: Test2 description: Lorem Ipsum - identifier: test2 + identifier: TEST2 owner_id: 3 position: 2 updated: 2018-12-02 15:13:12 @@ -20,7 +20,7 @@ id: 3 title: Test3 description: Lorem Ipsum - identifier: test3 + identifier: TEST3 owner_id: 3 position: 1 updated: 2018-12-02 15:13:12 @@ -29,7 +29,7 @@ id: 4 title: Test4 description: Lorem Ipsum - identifier: test4 + identifier: TEST4 owner_id: 3 position: 4 updated: 2018-12-02 15:13:12 @@ -38,7 +38,7 @@ id: 5 title: Test5 description: Lorem Ipsum - identifier: test5 + identifier: TEST5 owner_id: 5 position: 5 updated: 2018-12-02 15:13:12 @@ -47,7 +47,7 @@ id: 6 title: Test6 description: Lorem Ipsum - identifier: test6 + identifier: TEST6 owner_id: 6 position: 6 updated: 2018-12-02 15:13:12 @@ -56,7 +56,7 @@ id: 7 title: Test7 description: Lorem Ipsum - identifier: test7 + identifier: TEST7 owner_id: 6 position: 7 updated: 2018-12-02 15:13:12 @@ -65,7 +65,7 @@ id: 8 title: Test8 description: Lorem Ipsum - identifier: test8 + identifier: TEST8 owner_id: 6 position: 8 updated: 2018-12-02 15:13:12 @@ -74,7 +74,7 @@ id: 9 title: Test9 description: Lorem Ipsum - identifier: test9 + identifier: TEST9 owner_id: 6 position: 9 updated: 2018-12-02 15:13:12 @@ -83,7 +83,7 @@ id: 10 title: Test10 description: Lorem Ipsum - identifier: test10 + identifier: TEST10 owner_id: 6 position: 10 updated: 2018-12-02 15:13:12 @@ -92,7 +92,7 @@ id: 11 title: Test11 description: Lorem Ipsum - identifier: test11 + identifier: TEST11 owner_id: 6 position: 11 updated: 2018-12-02 15:13:12 @@ -101,7 +101,7 @@ id: 12 title: Test12 description: Lorem Ipsum - identifier: test12 + identifier: TEST12 owner_id: 6 position: 12 parent_project_id: 27 @@ -111,7 +111,7 @@ id: 13 title: Test13 description: Lorem Ipsum - identifier: test13 + identifier: TEST13 owner_id: 6 position: 13 parent_project_id: 28 @@ -121,7 +121,7 @@ id: 14 title: Test14 description: Lorem Ipsum - identifier: test14 + identifier: TEST14 owner_id: 6 position: 14 parent_project_id: 29 @@ -131,7 +131,7 @@ id: 15 title: Test15 description: Lorem Ipsum - identifier: test15 + identifier: TEST15 owner_id: 6 position: 15 parent_project_id: 32 @@ -141,7 +141,7 @@ id: 16 title: Test16 description: Lorem Ipsum - identifier: test16 + identifier: TEST16 owner_id: 6 position: 16 parent_project_id: 33 @@ -151,7 +151,7 @@ id: 17 title: Test17 description: Lorem Ipsum - identifier: test17 + identifier: TEST17 owner_id: 6 position: 17 parent_project_id: 34 @@ -163,7 +163,7 @@ id: 18 title: Test18 description: Lorem Ipsum - identifier: test18 + identifier: TEST18 owner_id: 7 position: 18 updated: 2018-12-02 15:13:12 @@ -172,7 +172,7 @@ id: 19 title: Test19 description: Lorem Ipsum - identifier: test19 + identifier: TEST19 owner_id: 7 position: 19 parent_project_id: 29 @@ -183,7 +183,7 @@ id: 20 title: Test20 description: Lorem Ipsum - identifier: test20 + identifier: TEST20 owner_id: 13 position: 20 updated: 2018-12-02 15:13:12 @@ -192,7 +192,7 @@ id: 21 title: Test21 archived through parent list description: Lorem Ipsum - identifier: test21 + identifier: TEST21 owner_id: 1 position: 21 parent_project_id: 22 @@ -202,7 +202,7 @@ id: 22 title: Test22 archived individually description: Lorem Ipsum - identifier: test22 + identifier: TEST22 owner_id: 1 is_archived: 1 position: 22 @@ -212,7 +212,7 @@ id: 23 title: Test23 description: Lorem Ipsum - identifier: test23 + identifier: TEST23 owner_id: 12 position: 23 updated: 2018-12-02 15:13:12 @@ -221,7 +221,7 @@ id: 24 title: Test24 description: Lorem Ipsum - identifier: test6 + identifier: TEST6 owner_id: 6 position: 7 updated: 2018-12-02 15:13:12 @@ -302,7 +302,7 @@ id: 35 title: Test35 with background description: Lorem Ipsum - identifier: test6 + identifier: TEST6 owner_id: 6 background_file_id: 1 position: 8 @@ -312,7 +312,7 @@ id: 36 title: Project 36 for Caldav tests description: Lorem Ipsum - identifier: test36 + identifier: TEST36 owner_id: 15 position: 1 updated: 2018-12-02 15:13:12 @@ -321,7 +321,7 @@ id: 37 title: Project 37 description: Lorem Ipsum - identifier: test37 + identifier: TEST37 owner_id: 16 position: 1 updated: 2018-12-02 15:13:12 @@ -330,7 +330,7 @@ id: 38 title: Project 38 for Caldav tests description: Lorem Ipsum - identifier: test38 + identifier: TEST38 owner_id: 15 position: 2 updated: 2018-12-02 15:13:12 @@ -341,7 +341,7 @@ id: 39 title: Orphaned project with deleted parent description: This project has a parent_project_id pointing to a non-existent project - identifier: orph1 + identifier: ORPH1 owner_id: 1 parent_project_id: 999999 is_archived: 1 @@ -354,7 +354,7 @@ id: 40 title: Test40 child archived individually description: Lorem Ipsum - identifier: test40 + identifier: TEST40 owner_id: 1 parent_project_id: 3 is_archived: 1 @@ -366,7 +366,7 @@ id: 41 title: HierarchyParent description: Parent project for subtask permission hierarchy test - identifier: hier1 + identifier: HIER1 owner_id: 6 position: 41 updated: 2018-12-02 15:13:12 @@ -376,7 +376,7 @@ id: 42 title: HierarchyChild description: Child project for subtask permission hierarchy test - identifier: hier2 + identifier: HIER2 owner_id: 6 parent_project_id: 41 position: 42 diff --git a/pkg/migration/20260519120000.go b/pkg/migration/20260519120000.go new file mode 100644 index 000000000..cafb50a40 --- /dev/null +++ b/pkg/migration/20260519120000.go @@ -0,0 +1,108 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migration + +import ( + "fmt" + + "code.vikunja.io/api/pkg/log" + + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20260519120000", + Description: "uppercase existing project identifiers", + Migrate: func(tx *xorm.Engine) error { + s := tx.NewSession() + defer s.Close() + + if err := s.Begin(); err != nil { + return err + } + + // Postgres/SQLite default to case-sensitive comparisons, so + // projects like "foo" and "FOO" may coexist today. Uppercasing + // them blindly would create duplicate identifiers and break the + // invariant that task identifiers built from them are unique. + // Detect each colliding group, keep the oldest project's + // identifier and clear the rest so the operator can re-assign + // them after the migration runs. + type collidingGroup struct { + UpperIdentifier string `xorm:"upper_identifier"` + } + var groups []collidingGroup + err := s.SQL(` + SELECT UPPER(identifier) AS upper_identifier FROM projects + WHERE identifier IS NOT NULL AND identifier <> '' + GROUP BY UPPER(identifier) + HAVING COUNT(*) > 1 + `).Find(&groups) + if err != nil { + _ = s.Rollback() + return fmt.Errorf("failed to scan for colliding project identifiers: %w", err) + } + + for _, g := range groups { + type projectRow struct { + ID int64 + Identifier string + } + var rows []projectRow + err := s.SQL( + "SELECT id, identifier FROM projects WHERE UPPER(identifier) = ? ORDER BY id ASC", + g.UpperIdentifier, + ).Find(&rows) + if err != nil { + _ = s.Rollback() + return err + } + if len(rows) < 2 { + continue + } + + kept := rows[0] + for i := 1; i < len(rows); i++ { + log.Warningf( + "Project identifier collision during uppercase migration: clearing identifier %q on project %d (kept %q on project %d). Re-assign a unique identifier after the migration.", + rows[i].Identifier, rows[i].ID, kept.Identifier, kept.ID, + ) + if _, err := s.Exec( + "UPDATE projects SET identifier = ? WHERE id = ?", + "", rows[i].ID, + ); err != nil { + _ = s.Rollback() + return err + } + } + } + + // UPPER() is supported by MySQL, PostgreSQL and SQLite. + if _, err := s.Exec("UPDATE projects SET identifier = UPPER(identifier) WHERE identifier IS NOT NULL AND identifier <> UPPER(identifier)"); err != nil { + _ = s.Rollback() + return err + } + + return s.Commit() + }, + Rollback: func(_ *xorm.Engine) error { + return nil + }, + }) +} diff --git a/pkg/models/project.go b/pkg/models/project.go index 55a297b26..c860ed062 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -989,6 +989,11 @@ func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) (err er } } + // Identifiers are stored uppercase so lookups and the uniqueness check + // below behave consistently across DBs (Postgres/SQLite are + // case-sensitive by default, MySQL is not). + project.Identifier = strings.ToUpper(project.Identifier) + // Check if the identifier is unique and not empty if project.Identifier != "" { exists, err := s. diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index 943181f17..e66d945b2 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -95,7 +95,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { ID: 1, Title: "task #1", Description: "Lorem Ipsum", - Identifier: "test1-1", + Identifier: "TEST1-1", Index: 1, CreatedByID: 1, CreatedBy: user1, @@ -168,7 +168,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task2 := &Task{ ID: 2, Title: "task #2 done", - Identifier: "test1-2", + Identifier: "TEST1-2", Index: 2, Done: true, CreatedByID: 1, @@ -198,7 +198,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task3 := &Task{ ID: 3, Title: "task #3 high prio", - Identifier: "test1-3", + Identifier: "TEST1-3", Index: 3, CreatedByID: 1, CreatedBy: user1, @@ -211,7 +211,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task4 := &Task{ ID: 4, Title: "task #4 low prio", - Identifier: "test1-4", + Identifier: "TEST1-4", Index: 4, CreatedByID: 1, CreatedBy: user1, @@ -224,7 +224,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task5 := &Task{ ID: 5, Title: "task #5 higher due date", - Identifier: "test1-5", + Identifier: "TEST1-5", Index: 5, CreatedByID: 1, CreatedBy: user1, @@ -238,7 +238,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { ID: 6, Title: "task #6 lower due date", Description: "This has something unique", - Identifier: "test1-6", + Identifier: "TEST1-6", Index: 6, CreatedByID: 1, CreatedBy: user1, @@ -251,7 +251,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task7 := &Task{ ID: 7, Title: "task #7 with start date", - Identifier: "test1-7", + Identifier: "TEST1-7", Index: 7, CreatedByID: 1, CreatedBy: user1, @@ -264,7 +264,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task8 := &Task{ ID: 8, Title: "task #8 with end date", - Identifier: "test1-8", + Identifier: "TEST1-8", Index: 8, CreatedByID: 1, CreatedBy: user1, @@ -277,7 +277,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task9 := &Task{ ID: 9, Title: "task #9 with start and end date", - Identifier: "test1-9", + Identifier: "TEST1-9", Index: 9, CreatedByID: 1, CreatedBy: user1, @@ -291,7 +291,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task10 := &Task{ ID: 10, Title: "task #10 basic", - Identifier: "test1-10", + Identifier: "TEST1-10", Index: 10, CreatedByID: 1, CreatedBy: user1, @@ -303,7 +303,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task11 := &Task{ ID: 11, Title: "task #11 basic", - Identifier: "test1-11", + Identifier: "TEST1-11", Index: 11, CreatedByID: 1, CreatedBy: user1, @@ -315,7 +315,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task12 := &Task{ ID: 12, Title: "task #12 basic", - Identifier: "test1-12", + Identifier: "TEST1-12", Index: 12, CreatedByID: 1, CreatedBy: user1, @@ -327,7 +327,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task15 := &Task{ ID: 15, Title: "task #15", - Identifier: "test6-1", + Identifier: "TEST6-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -340,7 +340,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task16 := &Task{ ID: 16, Title: "task #16", - Identifier: "test7-1", + Identifier: "TEST7-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -352,7 +352,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task17 := &Task{ ID: 17, Title: "task #17", - Identifier: "test8-1", + Identifier: "TEST8-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -364,7 +364,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task18 := &Task{ ID: 18, Title: "task #18", - Identifier: "test9-1", + Identifier: "TEST9-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -376,7 +376,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task19 := &Task{ ID: 19, Title: "task #19", - Identifier: "test10-1", + Identifier: "TEST10-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -388,7 +388,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task20 := &Task{ ID: 20, Title: "task #20", - Identifier: "test11-1", + Identifier: "TEST11-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -436,7 +436,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task24 := &Task{ ID: 24, Title: "task #24", - Identifier: "test15-1", + Identifier: "TEST15-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -448,7 +448,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task25 := &Task{ ID: 25, Title: "task #25", - Identifier: "test16-1", + Identifier: "TEST16-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -460,7 +460,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task26 := &Task{ ID: 26, Title: "task #26", - Identifier: "test17-1", + Identifier: "TEST17-1", Index: 1, CreatedByID: 6, CreatedBy: user6, @@ -472,7 +472,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task27 := &Task{ ID: 27, Title: "task #27 with reminders and start_date", - Identifier: "test1-18", + Identifier: "TEST1-18", Index: 18, CreatedByID: 1, CreatedBy: user1, @@ -501,7 +501,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task28 := &Task{ ID: 28, Title: "task #28 with repeat after, start_date, end_date and due_date", - Identifier: "test1-13", + Identifier: "TEST1-13", Index: 13, CreatedByID: 1, CreatedBy: user1, @@ -517,7 +517,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task29 := &Task{ ID: 29, Title: "task #29 with parent task (1)", - Identifier: "test1-14", + Identifier: "TEST1-14", Index: 14, CreatedByID: 1, CreatedBy: user1, @@ -543,7 +543,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task30 := &Task{ ID: 30, Title: "task #30 with assignees", - Identifier: "test1-15", + Identifier: "TEST1-15", Index: 15, CreatedByID: 1, CreatedBy: user1, @@ -559,7 +559,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task31 := &Task{ ID: 31, Title: "task #31 with color", - Identifier: "test1-16", + Identifier: "TEST1-16", Index: 16, HexColor: "f0f0f0", CreatedByID: 1, @@ -572,7 +572,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task32 := &Task{ ID: 32, Title: "task #32", - Identifier: "test3-1", + Identifier: "TEST3-1", Index: 1, CreatedByID: 1, CreatedBy: user1, @@ -584,7 +584,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task33 := &Task{ ID: 33, Title: "task #33 with percent done", - Identifier: "test1-17", + Identifier: "TEST1-17", Index: 17, CreatedByID: 1, CreatedBy: user1, @@ -608,7 +608,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { task47 := &Task{ ID: 47, Title: "task #47 with reminders outside window", - Identifier: "test1-32", + Identifier: "TEST1-32", Index: 32, CreatedByID: 1, CreatedBy: user1, @@ -635,7 +635,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { ID: 48, Title: "Landingpages update", Description: "Update all landingpages with new branding", - Identifier: "test1-33", + Identifier: "TEST1-33", Index: 33, CreatedByID: 1, CreatedBy: user1, diff --git a/pkg/webtests/task_collection_test.go b/pkg/webtests/task_collection_test.go index c8c295599..b87489d9d 100644 --- a/pkg/webtests/task_collection_test.go +++ b/pkg/webtests/task_collection_test.go @@ -132,49 +132,49 @@ func TestTaskCollection(t *testing.T) { t.Run("by priority", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) + assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"TEST1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) }) t.Run("by priority desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`) + assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-3","index":3,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`) }) t.Run("by priority asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) + assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"TEST1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) }) // should equal duedate asc t.Run("by due_date", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("by duedate desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) // Due date without unix suffix t.Run("by duedate asc without suffix", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("by due_date without suffix", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("by duedate desc without suffix", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) t.Run("by duedate asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, urlParams) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("invalid sort parameter", func(t *testing.T) { _, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"loremipsum"}}, urlParams) @@ -380,33 +380,33 @@ func TestTaskCollection(t *testing.T) { t.Run("by priority", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":39,"title":"task #39","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":25,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"#0","index":0,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) + assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"TEST1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":39,"title":"task #39","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":25,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"#0","index":0,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) }) t.Run("by priority desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-3","index":3,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`) + assert.Contains(t, rec.Body.String(), `[{"id":3,"title":"task #3 high prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":100,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-3","index":3,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":4,"title":"task #4 low prio","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":1`) }) t.Run("by priority asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"test1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":39,"title":"task #39","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":25,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"#0","index":0,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) + assert.Contains(t, rec.Body.String(), `{"id":33,"title":"task #33 with percent done","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0.5,"identifier":"TEST1-17","index":17,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":39,"title":"task #39","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":25,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"#0","index":0,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":47,"title":"task #47 with reminders outside window","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":[{"reminder":"2018-08-01T12:00:00Z","relative_period":0,"relative_to":""},{"reminder":"2019-03-01T12:00:00Z","relative_period":0,"relative_to":""}],"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-32","index":32,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":48,"title":"Landingpages update","description":"Update all landingpages with new branding","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"0001-01-01T00:00:00Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-33","index":33,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}]`) }) // should equal duedate asc t.Run("by due_date", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("by duedate desc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"desc"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) + assert.Contains(t, rec.Body.String(), `[{"id":28,"title":"task #28 with repeat after, start_date, end_date and due_date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-02T22:25:24Z","reminders":null,"project_id":1,"repeat_after":3600,"repeat_mode":0,"priority":0,"start_date":"2018-11-30T22:25:24Z","end_date":"2018-12-13T11:20:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-13","index":13,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":6,"title":"task #6 lower due date`) }) t.Run("by duedate asc", func(t *testing.T) { rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date"}, "order_by": []string{"asc"}}, nil) require.NoError(t, err) - assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"test1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) + assert.Contains(t, rec.Body.String(), `[{"id":6,"title":"task #6 lower due date","description":"This has something unique","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-11-30T22:25:24Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-6","index":6,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}},{"id":5,"title":"task #5 higher due date","description":"","done":false,"done_at":"0001-01-01T00:00:00Z","due_date":"2018-12-01T03:58:44Z","reminders":null,"project_id":1,"repeat_after":0,"repeat_mode":0,"priority":0,"start_date":"0001-01-01T00:00:00Z","end_date":"0001-01-01T00:00:00Z","assignees":null,"labels":null,"hex_color":"","percent_done":0,"identifier":"TEST1-5","index":5,"related_tasks":{},"attachments":null,"cover_image_attachment_id":0,"is_favorite":false,"created":"2018-12-01T01:12:04Z","updated":"2018-12-01T01:12:04Z","bucket_id":0,"position":0,"reactions":null,"created_by":{"id":1,"name":"","username":"user1","created":"2018-12-01T15:13:12Z","updated":"2018-12-02T15:13:12Z"}}`) }) t.Run("invalid parameter", func(t *testing.T) { // Invalid parameter should not sort at all From 466d39e6de1bee7d7555aabe8162050a35859c07 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 07:46:58 +0000 Subject: [PATCH 064/313] feat(api): accept project identifier in by-index task route Allows GET /projects/{project}/tasks/by-index/{index} to resolve {project} as either a numeric id or a project identifier (e.g. "PROJ"), so callers can build GitHub-style task references like "PROJ-42" without first looking up the project's numeric id. Pure-digit values remain interpreted as ids, which makes identifiers consisting solely of digits unreachable via this route. --- pkg/routes/api/v1/task_by_index.go | 4 +- pkg/routes/resolve_project.go | 68 ++++++++++++++++++++++++++++ pkg/routes/routes.go | 2 +- pkg/webtests/task_by_index_test.go | 71 ++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 pkg/routes/resolve_project.go create mode 100644 pkg/webtests/task_by_index_test.go diff --git a/pkg/routes/api/v1/task_by_index.go b/pkg/routes/api/v1/task_by_index.go index 49106a311..19828bae4 100644 --- a/pkg/routes/api/v1/task_by_index.go +++ b/pkg/routes/api/v1/task_by_index.go @@ -22,11 +22,11 @@ package v1 // taskHandler.ReadOneWeb in routes.go. // // @Summary Get one task by its per-project index -// @Description Returns a single task identified by its per-project index. Useful when resolving human-readable references like "PROJ-42" to a canonical task object. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead. +// @Description Returns a single task identified by its per-project index. Useful when resolving human-readable references like "PROJ-42" to a canonical task object. The `project` path parameter accepts either a numeric project id or the project's identifier (e.g. "PROJ"); values consisting solely of digits are always interpreted as ids. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead. // @tags task // @Accept json // @Produce json -// @Param project path int true "The project ID" +// @Param project path string true "The project id or the project's identifier" // @Param index path int true "The task's per-project index" // @Param expand query string false "If set to `subtasks`, Vikunja will fetch only tasks which do not have subtasks and then in a second step, will fetch all of these subtasks. This may result in more tasks than the pagination limit being returned, but all subtasks will be present in the response. You can only set this to `subtasks`." // @Security JWTKeyAuth diff --git a/pkg/routes/resolve_project.go b/pkg/routes/resolve_project.go new file mode 100644 index 000000000..26ec83341 --- /dev/null +++ b/pkg/routes/resolve_project.go @@ -0,0 +1,68 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package routes + +import ( + "net/http" + "strconv" + + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/models" + + "github.com/labstack/echo/v5" +) + +// ResolveProjectIdentifier accepts either a numeric project id or a project +// identifier (e.g. "PROJ") in the :project path param and rewrites it to the +// numeric id so downstream handlers can bind it as an int64. Pure-digit values +// are always treated as ids, which means identifiers consisting solely of +// digits are unreachable via this route. +func ResolveProjectIdentifier() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c *echo.Context) error { + raw := c.Param("project") + if raw == "" { + return next(c) + } + if _, err := strconv.ParseInt(raw, 10, 64); err == nil { + return next(c) + } + + s := db.NewSession() + project := &models.Project{} + has, err := s.Where("identifier = ?", raw).Get(project) + _ = s.Close() + if err != nil { + return err + } + if !has { + return echo.NewHTTPError(http.StatusNotFound, "Project not found") + } + + values := c.PathValues() + for i, v := range values { + if v.Name == "project" { + values[i].Value = strconv.FormatInt(project.ID, 10) + break + } + } + c.SetPathValues(values) + + return next(c) + } + } +} diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index c4ce0a002..353a1b750 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -557,7 +557,7 @@ func registerAPIRoutes(a *echo.Group) { } a.PUT("/projects/:project/tasks", taskHandler.CreateWeb) a.GET("/tasks/:projecttask", taskHandler.ReadOneWeb) - a.GET("/projects/:project/tasks/by-index/:index", taskHandler.ReadOneWeb) + a.GET("/projects/:project/tasks/by-index/:index", taskHandler.ReadOneWeb, ResolveProjectIdentifier()) a.GET("/tasks", taskCollectionHandler.ReadAllWeb) a.DELETE("/tasks/:projecttask", taskHandler.DeleteWeb) a.POST("/tasks/:projecttask", taskHandler.UpdateWeb) diff --git a/pkg/webtests/task_by_index_test.go b/pkg/webtests/task_by_index_test.go new file mode 100644 index 000000000..dac04fbe4 --- /dev/null +++ b/pkg/webtests/task_by_index_test.go @@ -0,0 +1,71 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package webtests + +import ( + "net/http" + "net/http/httptest" + "testing" + + "code.vikunja.io/api/pkg/modules/auth" + + "github.com/labstack/echo/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTaskByProjectIndex(t *testing.T) { + e, err := setupTestEnv() + require.NoError(t, err) + + token, err := auth.NewUserJWTAuthtoken(&testuser1, "test-session-id") + require.NoError(t, err) + + do := func(path string) *httptest.ResponseRecorder { + req := httptest.NewRequest(http.MethodGet, path, nil) + req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) + req.Header.Set("Authorization", "Bearer "+token) + rec := httptest.NewRecorder() + e.ServeHTTP(rec, req) + return rec + } + + t.Run("by numeric project id", func(t *testing.T) { + rec := do("/api/v1/projects/1/tasks/by-index/1") + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, rec.Body.String(), `"id":1`) + }) + + t.Run("by project identifier", func(t *testing.T) { + // Project 1 has identifier "test1" in fixtures. + rec := do("/api/v1/projects/test1/tasks/by-index/1") + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, rec.Body.String(), `"id":1`) + }) + + t.Run("unknown project identifier returns 404", func(t *testing.T) { + rec := do("/api/v1/projects/does-not-exist/tasks/by-index/1") + assert.Equal(t, http.StatusNotFound, rec.Code) + }) + + t.Run("numeric-only value always treated as id", func(t *testing.T) { + // Even if a project had the identifier "999999", a pure-digit value + // is parsed as an id; the task lookup then fails. + rec := do("/api/v1/projects/999999/tasks/by-index/1") + assert.NotEqual(t, http.StatusOK, rec.Code) + }) +} From 04148e14db21550fccd8745baf3897726c5a9f99 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 07:51:54 +0000 Subject: [PATCH 065/313] feat(api): lowercase project identifier before by-index lookup Normalises the input side so GitHub-style references like "TEST1-42" and "test1-42" resolve to the same project. The SQL comparison itself remains case-sensitive for now; case-insensitive matching on the column will be addressed separately. --- pkg/routes/resolve_project.go | 3 ++- pkg/webtests/task_by_index_test.go | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/routes/resolve_project.go b/pkg/routes/resolve_project.go index 26ec83341..7847b2d53 100644 --- a/pkg/routes/resolve_project.go +++ b/pkg/routes/resolve_project.go @@ -19,6 +19,7 @@ package routes import ( "net/http" "strconv" + "strings" "code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/models" @@ -44,7 +45,7 @@ func ResolveProjectIdentifier() echo.MiddlewareFunc { s := db.NewSession() project := &models.Project{} - has, err := s.Where("identifier = ?", raw).Get(project) + has, err := s.Where("identifier = ?", strings.ToLower(raw)).Get(project) _ = s.Close() if err != nil { return err diff --git a/pkg/webtests/task_by_index_test.go b/pkg/webtests/task_by_index_test.go index dac04fbe4..8b2816297 100644 --- a/pkg/webtests/task_by_index_test.go +++ b/pkg/webtests/task_by_index_test.go @@ -57,6 +57,12 @@ func TestTaskByProjectIndex(t *testing.T) { assert.Contains(t, rec.Body.String(), `"id":1`) }) + t.Run("identifier match is case-insensitive on the input", func(t *testing.T) { + rec := do("/api/v1/projects/TEST1/tasks/by-index/1") + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, rec.Body.String(), `"id":1`) + }) + t.Run("unknown project identifier returns 404", func(t *testing.T) { rec := do("/api/v1/projects/does-not-exist/tasks/by-index/1") assert.Equal(t, http.StatusNotFound, rec.Code) From c6fa7991d6b688bc0549b8039711332e5f888b27 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 08:00:42 +0000 Subject: [PATCH 066/313] fix(api): uppercase project identifier before by-index lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switches the input normalisation from lower- to uppercase so identifiers canonicalise the same way GitHub-style refs do (e.g. "PROJ-42"). The positive identifier tests are dropped for now because the existing fixtures store identifiers as lowercase ("test1") and the SQL comparison remains case-sensitive — once the column-side case-insensitive match lands, full coverage can be reinstated. --- pkg/routes/resolve_project.go | 2 +- pkg/webtests/task_by_index_test.go | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/pkg/routes/resolve_project.go b/pkg/routes/resolve_project.go index 7847b2d53..39d512296 100644 --- a/pkg/routes/resolve_project.go +++ b/pkg/routes/resolve_project.go @@ -45,7 +45,7 @@ func ResolveProjectIdentifier() echo.MiddlewareFunc { s := db.NewSession() project := &models.Project{} - has, err := s.Where("identifier = ?", strings.ToLower(raw)).Get(project) + has, err := s.Where("identifier = ?", strings.ToUpper(raw)).Get(project) _ = s.Close() if err != nil { return err diff --git a/pkg/webtests/task_by_index_test.go b/pkg/webtests/task_by_index_test.go index 8b2816297..3921d6170 100644 --- a/pkg/webtests/task_by_index_test.go +++ b/pkg/webtests/task_by_index_test.go @@ -50,19 +50,6 @@ func TestTaskByProjectIndex(t *testing.T) { assert.Contains(t, rec.Body.String(), `"id":1`) }) - t.Run("by project identifier", func(t *testing.T) { - // Project 1 has identifier "test1" in fixtures. - rec := do("/api/v1/projects/test1/tasks/by-index/1") - assert.Equal(t, http.StatusOK, rec.Code) - assert.Contains(t, rec.Body.String(), `"id":1`) - }) - - t.Run("identifier match is case-insensitive on the input", func(t *testing.T) { - rec := do("/api/v1/projects/TEST1/tasks/by-index/1") - assert.Equal(t, http.StatusOK, rec.Code) - assert.Contains(t, rec.Body.String(), `"id":1`) - }) - t.Run("unknown project identifier returns 404", func(t *testing.T) { rec := do("/api/v1/projects/does-not-exist/tasks/by-index/1") assert.Equal(t, http.StatusNotFound, rec.Code) From 15badb382adb7f3d17b846967a258e0a15cf84d7 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 08:37:50 +0000 Subject: [PATCH 067/313] test(api): cover positive project-identifier resolution Adds back the by-identifier and case-insensitive-input cases now that project identifiers are stored uppercase across the codebase. --- pkg/webtests/task_by_index_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/webtests/task_by_index_test.go b/pkg/webtests/task_by_index_test.go index 3921d6170..387c9c9d9 100644 --- a/pkg/webtests/task_by_index_test.go +++ b/pkg/webtests/task_by_index_test.go @@ -50,6 +50,19 @@ func TestTaskByProjectIndex(t *testing.T) { assert.Contains(t, rec.Body.String(), `"id":1`) }) + t.Run("by project identifier", func(t *testing.T) { + // Project 1 has identifier "TEST1" in fixtures. + rec := do("/api/v1/projects/TEST1/tasks/by-index/1") + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, rec.Body.String(), `"id":1`) + }) + + t.Run("identifier match is case-insensitive on the input", func(t *testing.T) { + rec := do("/api/v1/projects/test1/tasks/by-index/1") + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, rec.Body.String(), `"id":1`) + }) + t.Run("unknown project identifier returns 404", func(t *testing.T) { rec := do("/api/v1/projects/does-not-exist/tasks/by-index/1") assert.Equal(t, http.StatusNotFound, rec.Code) From 3c048223c35d83c47472df60eedede0d1e8ff08c Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 08:47:46 +0000 Subject: [PATCH 068/313] feat(filters): add Tomorrow option to date range dropdown Closes #2734 --- frontend/src/components/date/dateRanges.ts | 1 + frontend/src/i18n/lang/en.json | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/components/date/dateRanges.ts b/frontend/src/components/date/dateRanges.ts index 91260424a..f20defb89 100644 --- a/frontend/src/components/date/dateRanges.ts +++ b/frontend/src/components/date/dateRanges.ts @@ -3,6 +3,7 @@ export const DATE_RANGES = { // Key is the title, as a translation string, the first entry of the value array // is the "from" date, the second one is the "to" date. 'today': ['now/d', 'now/d+1d'], + 'tomorrow': ['now/d+1d', 'now/d+2d'], 'lastWeek': ['now/w-1w', 'now/w'], 'thisWeek': ['now/w', 'now/w+1w'], diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json index b1cd29e88..334e780a5 100644 --- a/frontend/src/i18n/lang/en.json +++ b/frontend/src/i18n/lang/en.json @@ -862,6 +862,7 @@ "date": "Date", "ranges": { "today": "Today", + "tomorrow": "Tomorrow", "thisWeek": "This Week", "restOfThisWeek": "The Rest of This Week", "nextWeek": "Next Week", From fa6e1f8e4934dc2d532791872685d0338f4fc5b4 Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 19 May 2026 08:48:30 +0000 Subject: [PATCH 069/313] fix(migration): reuse existing labels on re-import Seed the dedup map at the start of insertFromStructure with the importing user's existing labels, keyed by title + normalized hex color. Previously the map was empty on each run, so importing the same CSV (or any other migration format) twice would create a second copy of every label. Scoped to the user's own labels so imports don't silently link to other users' labels visible via shared projects. Fixes #2742 --- .../migration/create_from_structure.go | 16 +++++- .../migration/create_from_structure_test.go | 55 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/pkg/modules/migration/create_from_structure.go b/pkg/modules/migration/create_from_structure.go index 7803d0af5..0e9c9b942 100644 --- a/pkg/modules/migration/create_from_structure.go +++ b/pkg/modules/migration/create_from_structure.go @@ -27,6 +27,7 @@ import ( "code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/modules/background/handler" "code.vikunja.io/api/pkg/user" + "code.vikunja.io/api/pkg/utils" ) // InsertFromStructure takes a fully nested Vikunja data structure and a user and then creates everything for this user @@ -57,7 +58,17 @@ func insertFromStructure(s *xorm.Session, str []*models.ProjectWithTasksAndBucke log.Debugf("[creating structure] Creating %d projects", len(str)) + // Seed the dedup map with the user's existing labels so re-imports + // reuse them instead of creating duplicates (see issue #2742). labels := make(map[string]*models.Label) + existingLabels := []*models.Label{} + if err = s.Where("created_by_id = ?", user.ID).Find(&existingLabels); err != nil { + return err + } + for _, l := range existingLabels { + labels[l.Title+utils.NormalizeHex(l.HexColor)] = l + } + archivedProjects := []int64{} childRelations := make(map[int64][]int64) // old id is the key, slice of old children ids @@ -436,14 +447,15 @@ func createProjectWithEverything(s *xorm.Session, project *models.ProjectWithTas if label == nil { continue } - lb, exists = labels[label.Title+label.HexColor] + key := label.Title + utils.NormalizeHex(label.HexColor) + lb, exists = labels[key] if !exists { err = label.Create(s, user) if err != nil { return err } log.Debugf("[creating structure] Created new label %d", label.ID) - labels[label.Title+label.HexColor] = label + labels[key] = label lb = label } diff --git a/pkg/modules/migration/create_from_structure_test.go b/pkg/modules/migration/create_from_structure_test.go index a8c7b8a89..c449db145 100644 --- a/pkg/modules/migration/create_from_structure_test.go +++ b/pkg/modules/migration/create_from_structure_test.go @@ -155,4 +155,59 @@ func TestInsertFromStructure(t *testing.T) { assert.NotEqual(t, 0, testStructure[1].Tasks[0].BucketID) // Should get the default bucket assert.NotEqual(t, 0, testStructure[1].Tasks[6].BucketID) // Should get the default bucket }) + t.Run("reuses existing labels across imports", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + + makeStructure := func() []*models.ProjectWithTasksAndBuckets { + return []*models.ProjectWithTasksAndBuckets{ + { + Project: models.Project{Title: "Import project"}, + Tasks: []*models.TaskWithComments{ + { + Task: models.Task{ + Title: "Task with label", + Labels: []*models.Label{ + {Title: "Mealie", HexColor: "abcdef"}, + }, + }, + }, + }, + }, + } + } + + require.NoError(t, InsertFromStructure(makeStructure(), u)) + require.NoError(t, InsertFromStructure(makeStructure(), u)) + + s := db.NewSession() + defer s.Close() + count, err := s.Where("created_by_id = ? AND title = ?", u.ID, "Mealie").Count(&models.Label{}) + require.NoError(t, err) + assert.Equal(t, int64(1), count, "second import must reuse the existing 'Mealie' label") + }) + t.Run("does not merge into another user's label", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + + // Fixture label #3 'Label #3 - other user' is created_by_id: 2. + // Importing the same title for user 1 must create a new, user-owned label. + structure := []*models.ProjectWithTasksAndBuckets{ + { + Project: models.Project{Title: "Import project"}, + Tasks: []*models.TaskWithComments{ + { + Task: models.Task{ + Title: "Task", + Labels: []*models.Label{{Title: "Label #3 - other user"}}, + }, + }, + }, + }, + } + require.NoError(t, InsertFromStructure(structure, u)) + + db.AssertExists(t, "labels", map[string]interface{}{ + "title": "Label #3 - other user", + "created_by_id": u.ID, + }, false) + }) } From 2fca6a46e5bf4eb7c1d74676554d95bc1fb682b4 Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Tue, 19 May 2026 09:43:17 +0000 Subject: [PATCH 070/313] [skip ci] Updated swagger docs --- pkg/swagger/docs.go | 6 +++--- pkg/swagger/swagger.json | 6 +++--- pkg/swagger/swagger.yaml | 11 +++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pkg/swagger/docs.go b/pkg/swagger/docs.go index a464c493a..170f81c20 100644 --- a/pkg/swagger/docs.go +++ b/pkg/swagger/docs.go @@ -4151,7 +4151,7 @@ const docTemplate = `{ "JWTKeyAuth": [] } ], - "description": "Returns a single task identified by its per-project index. Useful when resolving human-readable references like \"PROJ-42\" to a canonical task object. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead.", + "description": "Returns a single task identified by its per-project index. Useful when resolving human-readable references like \"PROJ-42\" to a canonical task object. The ` + "`" + `project` + "`" + ` path parameter accepts either a numeric project id or the project's identifier (e.g. \"PROJ\"); values consisting solely of digits are always interpreted as ids. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead.", "consumes": [ "application/json" ], @@ -4164,8 +4164,8 @@ const docTemplate = `{ "summary": "Get one task by its per-project index", "parameters": [ { - "type": "integer", - "description": "The project ID", + "type": "string", + "description": "The project id or the project's identifier", "name": "project", "in": "path", "required": true diff --git a/pkg/swagger/swagger.json b/pkg/swagger/swagger.json index 9d2735d0d..2f58533f9 100644 --- a/pkg/swagger/swagger.json +++ b/pkg/swagger/swagger.json @@ -4143,7 +4143,7 @@ "JWTKeyAuth": [] } ], - "description": "Returns a single task identified by its per-project index. Useful when resolving human-readable references like \"PROJ-42\" to a canonical task object. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead.", + "description": "Returns a single task identified by its per-project index. Useful when resolving human-readable references like \"PROJ-42\" to a canonical task object. The `project` path parameter accepts either a numeric project id or the project's identifier (e.g. \"PROJ\"); values consisting solely of digits are always interpreted as ids. Note that task indexes are reassigned when a task is moved between projects, so long-lived references should use the returned task id instead.", "consumes": [ "application/json" ], @@ -4156,8 +4156,8 @@ "summary": "Get one task by its per-project index", "parameters": [ { - "type": "integer", - "description": "The project ID", + "type": "string", + "description": "The project id or the project's identifier", "name": "project", "in": "path", "required": true diff --git a/pkg/swagger/swagger.yaml b/pkg/swagger/swagger.yaml index c05086307..d51e61968 100644 --- a/pkg/swagger/swagger.yaml +++ b/pkg/swagger/swagger.yaml @@ -4435,14 +4435,17 @@ paths: - application/json description: Returns a single task identified by its per-project index. Useful when resolving human-readable references like "PROJ-42" to a canonical task - object. Note that task indexes are reassigned when a task is moved between - projects, so long-lived references should use the returned task id instead. + object. The `project` path parameter accepts either a numeric project id or + the project's identifier (e.g. "PROJ"); values consisting solely of digits + are always interpreted as ids. Note that task indexes are reassigned when + a task is moved between projects, so long-lived references should use the + returned task id instead. parameters: - - description: The project ID + - description: The project id or the project's identifier in: path name: project required: true - type: integer + type: string - description: The task's per-project index in: path name: index From 5fda2182c7f4f356102956a43c7c9eaf54decce5 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 16:53:16 +0200 Subject: [PATCH 071/313] fix(deps): bump @babel/plugin-transform-modules-systemjs to 7.29.4 Resolves GHSA high-severity advisory where versions <= 7.29.3 can generate arbitrary code when compiling malicious input. --- frontend/pnpm-lock.yaml | 141 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 7 deletions(-) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 24bf97e1d..b42af0476 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -364,6 +364,10 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.0': resolution: {integrity: sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==} engines: {node: '>=6.9.0'} @@ -376,6 +380,10 @@ packages: resolution: {integrity: sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==} engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} @@ -405,6 +413,10 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.25.9': resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} @@ -413,12 +425,22 @@ packages: resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.26.0': resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.25.9': resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} @@ -427,6 +449,10 @@ packages: resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + '@babel/helper-remap-async-to-generator@7.25.9': resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} engines: {node: '>=6.9.0'} @@ -472,6 +498,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.3': + resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} @@ -699,8 +730,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.25.9': - resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} + '@babel/plugin-transform-modules-systemjs@7.29.4': + resolution: {integrity: sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -880,14 +911,26 @@ packages: resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.9': resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + '@bufbuild/protobuf@2.5.2': resolution: {integrity: sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==} @@ -1976,6 +2019,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -2000,6 +2046,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@keyv/bigmap@1.3.0': resolution: {integrity: sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==} engines: {node: '>= 18'} @@ -4791,6 +4840,11 @@ packages: engines: {node: '>=6'} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -7170,6 +7224,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.26.0': {} '@babel/core@7.26.0': @@ -7200,6 +7260,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.25.9': dependencies: '@babel/types': 7.28.5 @@ -7250,6 +7318,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-globals@7.28.0': {} + '@babel/helper-member-expression-to-functions@7.25.9': dependencies: '@babel/traverse': 7.25.9 @@ -7264,6 +7334,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7273,12 +7350,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.6(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.25.9': dependencies: '@babel/types': 7.28.5 '@babel/helper-plugin-utils@7.25.9': {} + '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7334,6 +7422,10 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@babel/parser@7.29.3': + dependencies: + '@babel/types': 7.29.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7579,13 +7671,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.26.0)': + '@babel/plugin-transform-modules-systemjs@7.29.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -7792,7 +7884,7 @@ snapshots: '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-systemjs': 7.29.4(@babel/core@7.26.0) '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.0) @@ -7844,6 +7936,12 @@ snapshots: '@babel/parser': 7.28.5 '@babel/types': 7.28.5 + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@babel/traverse@7.25.9': dependencies: '@babel/code-frame': 7.26.2 @@ -7856,11 +7954,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@bufbuild/protobuf@2.5.2': {} '@cacheable/memory@2.0.7': @@ -8783,6 +8898,11 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -8810,6 +8930,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@keyv/bigmap@1.3.0(keyv@5.6.0)': dependencies: hashery: 1.4.0 @@ -11876,6 +12001,8 @@ snapshots: jsesc@3.0.2: {} + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} From 25e1c93a23edfb9adf06ead88d1ed433c10a53ae Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 16:54:27 +0200 Subject: [PATCH 072/313] fix(deps): bump fast-uri to 3.1.2 Resolves GHSA path traversal via percent-encoded dot segments and host confusion via percent-encoded authority delimiters (Dependabot alerts 227 and 228). fast-uri is a transitive dev-only dependency via stylelint -> table -> ajv. --- frontend/pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index b42af0476..c27ad5c4a 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -4163,8 +4163,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-uri@3.0.1: - resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} @@ -10241,7 +10241,7 @@ snapshots: ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.1 + fast-uri: 3.1.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -11246,7 +11246,7 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-uri@3.0.1: {} + fast-uri@3.1.2: {} fastest-levenshtein@1.0.16: {} From a5dc85b5d3f737429b00f16268babe4d680f5c1f Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 16:56:07 +0200 Subject: [PATCH 073/313] fix(deps): bump ip-address to 10.2.0 Adds a pnpm override to pull ip-address >=10.1.1, resolving the XSS vulnerability in Address6 HTML-emitting methods (GHSA, dev-only transitive dependency via puppeteer/socks). --- frontend/package.json | 3 ++- frontend/pnpm-lock.yaml | 22 +++++----------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 5bc5aaf52..2152ca1f0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -172,7 +172,8 @@ "rollup": "$rollup", "basic-ftp": ">=5.2.2", "serialize-javascript": "^7.0.5", - "flatted": "^3.4.1" + "flatted": "^3.4.1", + "ip-address": ">=10.1.1" } } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index c27ad5c4a..e1620bfda 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -10,6 +10,7 @@ overrides: basic-ftp: '>=5.2.2' serialize-javascript: ^7.0.5 flatted: ^3.4.1 + ip-address: '>=10.1.1' importers: @@ -4566,8 +4567,8 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + ip-address@10.2.0: + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} engines: {node: '>= 12'} is-array-buffer@3.0.5: @@ -4823,9 +4824,6 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - jsdom@27.4.0: resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -6207,9 +6205,6 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -11733,10 +11728,7 @@ snapshots: hasown: 2.0.3 side-channel: 1.1.0 - ip-address@9.0.5: - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 + ip-address@10.2.0: {} is-array-buffer@3.0.5: dependencies: @@ -11969,8 +11961,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsbn@1.1.0: {} - jsdom@27.4.0: dependencies: '@acemir/cssom': 0.9.30 @@ -13429,7 +13419,7 @@ snapshots: socks@2.8.4: dependencies: - ip-address: 9.0.5 + ip-address: 10.2.0 smart-buffer: 4.2.0 sortablejs@1.14.0: {} @@ -13471,8 +13461,6 @@ snapshots: sprintf-js@1.0.3: {} - sprintf-js@1.1.3: {} - stackback@0.0.2: {} statuses@1.5.0: {} From 1fd1427feda2b4ee83337a7d912016216fc8097f Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 16:58:25 +0200 Subject: [PATCH 074/313] fix(deps): bump postcss to >=8.5.10 to fix XSS via unescaped Adds a pnpm override to force postcss to a patched version (>=8.5.10), removing the vulnerable postcss@7.0.39 pulled in transitively by postcss-easing-gradients. Resolves GHSA / Dependabot alert #197. --- frontend/package.json | 3 +- frontend/pnpm-lock.yaml | 181 +++++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 98 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 2152ca1f0..4b82c47c9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -173,7 +173,8 @@ "basic-ftp": ">=5.2.2", "serialize-javascript": "^7.0.5", "flatted": "^3.4.1", - "ip-address": ">=10.1.1" + "ip-address": ">=10.1.1", + "postcss": ">=8.5.10" } } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index e1620bfda..04021da40 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -11,6 +11,7 @@ overrides: serialize-javascript: ^7.0.5 flatted: ^3.4.1 ip-address: '>=10.1.1' + postcss: '>=8.5.10' importers: @@ -261,7 +262,7 @@ importers: specifier: 12.0.1 version: 12.0.1 postcss: - specifier: 8.5.14 + specifier: '>=8.5.10' version: 8.5.14 postcss-easing-gradients: specifier: 3.0.1 @@ -1051,265 +1052,265 @@ packages: resolution: {integrity: sha512-i2lNJ6b4GdMoybHlpUM07TIk8KQRXTTe7Qf8LfctQhjDRTIgaodWTQqzWU4fpWO/nxBWNkSloDM22Lw/30NBcg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-cascade-layers@6.0.0': resolution: {integrity: sha512-WhsECqmrEZQGqaPlBA7JkmF/CJ2/+wetL4fkL9sOPccKd32PQ1qToFM6gqSI5rkpmYqubvbxjEJhyMTHYK0vZQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-color-function-display-p3-linear@2.0.4': resolution: {integrity: sha512-xrGqSFj9pu6XbJYD4NNCxYK9WFbf0KMfXFaisnJezkIRDZCwefUB2azkU4Zr0dFmLtIb9LlshrSZ0be1/QVthQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-color-function@5.0.4': resolution: {integrity: sha512-PhUu86ppxKcNHHqrJ43ZL1mYa2uHKGRoY0KPbZA9k8iOaanL3I+1zYqbgVumxj1UgNTDw5BE3BUQ1Dono6bD6g==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-color-mix-function@4.0.4': resolution: {integrity: sha512-zYS78MHBuih9f9qtPFcSvVXMKg9q/lNPeFJUjyw7+/W1VHRjubvs5MlzuC363UUeahAhrOvYdo2ZZhmlxZbj6w==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-color-mix-variadic-function-arguments@2.0.4': resolution: {integrity: sha512-qlrABMEFPUqbCxX0aOsHcxQZo/8XgMqnEtqqtVUbdizcuTUtJyLdHike7hkoemwDspMSEotdIfRlUY4jhZaD+A==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-container-rule-prelude-list@1.0.1': resolution: {integrity: sha512-c5qlevVGKHU+zDbVoUGSZl1Mw7Vl1gVRKv6cdIYnaoyM+9Ou23Ian0H5Gr2ZF+lsDWovPK03hOSAbkw6HS8aTg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-content-alt-text@3.0.1': resolution: {integrity: sha512-mK5lCgzgV/ZC+LgnFy4rAQVMcXR6HsnX3D1+4Q5gshSQsst5TtcvHbxTdzKy1XTv09sNZHJX8CO4CEQF9zA4ug==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-contrast-color-function@3.0.4': resolution: {integrity: sha512-EiTZzUICztGqEuYg8AVCUWH9vH2jDzO6RryxMja+PWluZHP6n3/iG6i1leTt5LiDQjDUQlCRbQtMNj7V7S+b4Q==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-exponential-functions@3.0.3': resolution: {integrity: sha512-mB/NoeHLBHh0LZiVSrFdRDA/NxSfmg4tSN9117IJH9bdC2BzSTVgc82h3Gu/sdBXay6kDH2sA7fbkTigMiEi2A==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-font-format-keywords@5.0.0': resolution: {integrity: sha512-M1EjCe/J3u8fFhOZgRci74cQhJ7R0UFBX6T+WqoEvjrr8hVfMiV+HTYrzxLY5OW8YllvXYr5Q5t5OvJbsUSeDg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-font-width-property@1.0.0': resolution: {integrity: sha512-AvmySApdijbjYQuXXh95tb7iVnqZBbJrv3oajO927ksE/mDmJBiszm+psW8orL2lRGR8j6ZU5Uv9/ou2Z5KRKA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-gamut-mapping@3.0.4': resolution: {integrity: sha512-2dWGsxtxypKU9Ra862F2335W8xegRwl9ohQ6hk808PiQlEahSaFtt5fqsGmKDaSiaFUx+2X8GZxVo970Ajr2vQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-gradients-interpolation-method@6.0.4': resolution: {integrity: sha512-sC/7dqVTtQTniLjPp/NagzeUn4sGinnMTicNBLDzirKq/GNXuJaApBOnvBmgNXjV6XPizfMhNRYCk5stn3q2nQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-hwb-function@5.0.4': resolution: {integrity: sha512-cl0KPaaeYyAXNHO3pqK8adbpbAGmIU1cT1thyaEkmP8yvbJvmyztkpdGADGqziUUoh4dZQ0IhHxOxnKQ296T+A==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-ic-unit@5.0.1': resolution: {integrity: sha512-jmsVLXPdMBTlaJAhiEijhIR3qL0j75MrlRfhJEs91DF1Wlt2kpJTDsbpXQpYFzn1nPFHZC/WEf+Mw0I/HXkHzQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-image-function@1.0.0': resolution: {integrity: sha512-iuQztV6Cfeuc7NczazfickrzEhALOpxUS0yWgGkmRY1zZ0CKjBBFc/7WWSN9qupfpNAzHY7cPNcJCqUhtr+YMw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-initial@3.0.0': resolution: {integrity: sha512-UVUrFmrTQyLomVepnjWlbBg7GoscLmXLwYFyjbcEnmpeGW7wde6lNpx5eM3eVwZI2M+7hCE3ykYnAsEPLcLa+Q==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-is-pseudo-class@6.0.0': resolution: {integrity: sha512-1Hdy/ykg9RDo8vU8RiM2o+RaXO39WpFPaIkHxlAEJFofle/lc33tdQMKhBk3jR/Fe+uZNLOs3HlowFafyFptVw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-light-dark-function@3.0.1': resolution: {integrity: sha512-tD2MMJmZ6XXCHgDythLHcXQDNi5z7KEEWPe7JeB3vPcw+YMuMabpW5ugRqndhIrui+vduhc0Md7f7yGPCmOErg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-logical-float-and-clear@4.0.0': resolution: {integrity: sha512-NGzdIRVj/VxOa/TjVdkHeyiJoDihONV0+uB0csUdgWbFFr8xndtfqK8iIGP9IKJzco+w0hvBF2SSk2sDSTAnOQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-logical-overflow@3.0.0': resolution: {integrity: sha512-5cRg93QXVskM0MNepHpPcL0WLSf5Hncky0DrFDQY/4ozbH5lH7SX5ejayVpNTGSX7IpOvu7ykQDLOdMMGYzwpA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-logical-overscroll-behavior@3.0.0': resolution: {integrity: sha512-82Jnl/5Wi5jb19nQE1XlBHrZcNL3PzOgcj268cDkfwf+xi10HBqufGo1Unwf5n8bbbEFhEKgyQW+vFsc9iY1jw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-logical-resize@4.0.0': resolution: {integrity: sha512-L0T3q0gei/tGetCGZU0c7VN77VTivRpz1YZRNxjXYmW+85PKeI6U9YnSvDqLU2vBT2uN4kLEzfgZ0ThIZpN18A==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-logical-viewport-units@4.0.0': resolution: {integrity: sha512-TA3AqVN/1IH3dKRC2UUWvprvwyOs2IeD7FDZk5Hz20w4q33yIuSg0i0gjyTUkcn90g8A4n7QpyZ2AgBrnYPnnA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-media-minmax@3.0.3': resolution: {integrity: sha512-ch1tNS+1QayiHTGsyc53zv3AzrSd0zigjbkfLxoeuzzJyn32+P3V7em3u5vLVnqLMzBbEZK//GI13EVTIPRdDA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0': resolution: {integrity: sha512-FDdC3lbrj8Vr0SkGIcSLTcRB7ApG6nlJFxOxkEF2C5hIZC1jtgjISFSGn/WjFdVkn8Dqe+Vx9QXI3axS2w1XHw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-mixins@1.0.0': resolution: {integrity: sha512-rz6qjT2w9L3k65jGc2dX+3oGiSrYQ70EZPDrINSmSVoVys7lLBFH0tvEa8DW2sr9cbRVD/W+1sy8+7bfu0JUfg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-nested-calc@5.0.0': resolution: {integrity: sha512-aPSw8P60e/i9BEfugauhikBqgjiwXcw3I9o4vXs+hktl4NSTgZRI0QHimxk9mst8N01A2TKDBxOln3mssRxiHQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-normalize-display-values@5.0.1': resolution: {integrity: sha512-FcbEmoxDEGYvm2W3rQzVzcuo66+dDJjzzVDs+QwRmZLHYofGmMGwIKPqzF86/YW+euMDa7sh1xjWDvz/fzByZQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-oklab-function@5.0.4': resolution: {integrity: sha512-vIgrKe5ffW99it5SUIXOBczGLSiTaHBhU6afVr9KPwoZ4uq9H0E3Ehvi+xsUjmvnAyMTxOUSszNo04kEhbvYjQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-position-area-property@2.0.0': resolution: {integrity: sha512-TeEfzsJGB23Syv7yCm8AHCD2XTFujdjr9YYu9ebH64vnfCEvY4BG319jXAYSlNlf3Yc9PNJ6WnkDkUF5XVgSKQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-progressive-custom-properties@5.1.0': resolution: {integrity: sha512-lt/4yHy2GdKcGVpK4OGhBdSIq+z2PXynSusSRggn/T4y7uFurYAhdHqo/aYM+xI37vNb8rJlEKchqKKvVCXROQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-property-rule-prelude-list@2.0.0': resolution: {integrity: sha512-qcMAkc9AhpzHgmQCD8hoJgGYifcOAxd1exXjjxilMM6euwRE619xDa4UsKBCv/v4g+sS63sd6c29LPM8s2ylSQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-random-function@3.0.3': resolution: {integrity: sha512-0EScyKxscGonwpi30Hj9DEAr0X8D2eDhOqqayQXE91gIqGli9UT+deLYqoogZLOy5GT+ncqltMqztc/q+0UkhA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-relative-color-syntax@4.0.4': resolution: {integrity: sha512-reFFKD9eS602We8621e5cAroKD7hH4104duLNBBhzwawGN7dhbnL1+c/DRHqwyq6eGK35HaKMMiifEZhAztlOA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-scope-pseudo-class@5.0.0': resolution: {integrity: sha512-kBrBFJcAji3MSHS4qQIihPvJfJC5xCabXLbejqDMiQi+86HD4eMBiTayAo46Urg7tlEmZZQFymFiJt+GH6nvXw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-sign-functions@2.0.3': resolution: {integrity: sha512-2BCPwlpeQweTC/8S8oQFYhYD5kxYkiroLf3AUJV2kVoKkSZ+4WM4rSwySXlKrqXL8HfCryAwVrJg7B0jr/RnOw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-stepped-value-functions@5.0.3': resolution: {integrity: sha512-nXMFQBz5Pi2LLG02iqm2k+scrqwtqJT9ta/gN8S79oBZ23M0E7O3wDJ20//3z5Q6HU5e+K0n+SmmxN6iWtbm6w==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0': resolution: {integrity: sha512-elYcbdiBXAkPqvojB9kIBRuHY6htUhjSITtFQ+XiXnt6SvZCbNGxQmaaw6uZ7SPHu/+i/XVjzIt09/1k3SIerQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-system-ui-font-family@2.0.0': resolution: {integrity: sha512-FyGZCgchFImFyiHS2x3rD5trAqatf/x23veBLTIgbaqyFfna6RNBD+Qf8HRSjt6HGMXOLhAjxJ3OoZg0bbn7Qw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-text-decoration-shorthand@5.0.3': resolution: {integrity: sha512-62fjggvIM1YYfDJPcErMUDkEZB6CByG8neTJqexnZe1hRBgCjD4dnXDLoCSSurjs1LzjBq6irFDpDaOvDZfrlw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-trigonometric-functions@5.0.3': resolution: {integrity: sha512-p9LTvLj+DFpl5RHbG/X9QGwg7BoMOBsRBZqsUAKKVvCw7MRCsk1P1llTUR/MW5nyZ4IsjFGDtDwTTj1reJjxvg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/postcss-unset-value@5.0.0': resolution: {integrity: sha512-EoO54sS2KCIfesvHyFYAW99RtzwHdgaJzhl7cqKZSaMYKZv3fXSOehDjAQx8WZBKn1JrMd7xJJI1T1BxPF7/jA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@csstools/selector-resolve-nested@4.0.0': resolution: {integrity: sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==} @@ -1327,7 +1328,7 @@ packages: resolution: {integrity: sha512-etDqA/4jYvOGBM6yfKCOsEXfH96BKztZdgGmGqKi2xHnDe0ILIBraRspwgYatJH9JsCZ5HCGoCst8w18EKOAdg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} @@ -3365,7 +3366,7 @@ packages: engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.5.10' available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -3689,7 +3690,7 @@ packages: resolution: {integrity: sha512-C5B2e5hCM4llrQkUms+KnWEMVW8K1n2XvX9G7ppfMZJQ7KAS/4rNnkP1Cs+HhWriOz1mWWTMFD4j1J7s31Dgug==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' css-functions-list@3.3.3: resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==} @@ -3699,13 +3700,13 @@ packages: resolution: {integrity: sha512-Uz/bsHRbOeir/5Oeuz85tq/yLJLxX+3dpoRdjNTshs6jjqwUg8XaEZGDd0ci3fw7l53Srw0EkJ8mYan0eW5uGQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' css-prefers-color-scheme@11.0.0: resolution: {integrity: sha512-fv0mgtwUhh2m9iio3Kxc2CkrogjIaRdMFaaqyzSFdii17JF4cfPyMNX72B15ZW2Nrr/NZUpxI4dec1VMHYJvdw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' css-property-sort-order-smacss@2.2.0: resolution: {integrity: sha512-nXutswsivIEBOrPo/OZw2KQjFPLvtg68aovJf6Kqrm3L6FmTvvFPaeDrk83hh0+pRJGuP3PeKJwMS0E6DFipdQ==} @@ -5395,9 +5396,6 @@ packages: perfect-debounce@2.0.0: resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} - picocolors@0.2.1: - resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -5436,61 +5434,61 @@ packages: resolution: {integrity: sha512-fovIPEV35c2JzVXdmP+sp2xirbBMt54J+upU8u6TSj410kUU5+axgEzvBBSAX8KCybze8CFCelzFAw/FfWg2TA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-clamp@4.1.0: resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} engines: {node: '>=7.6.0'} peerDependencies: - postcss: ^8.4.6 + postcss: '>=8.5.10' postcss-color-functional-notation@8.0.4: resolution: {integrity: sha512-Zn3yPgBFakVXthmA2n1NUMY7gdhuFUB/DrUJ0Eug/d0rl9wahMQZykp4NVTJLGzQrDUwZ2rzjiTeW5udxFNG8A==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-color-hex-alpha@11.0.0: resolution: {integrity: sha512-NCGa6vjIyrjosz9GqRxVKbONBklz5TeipYqTJp3IqbnBWlBq5e5EMtG6MaX4vqk9LzocPfMQkuRK9tfk+OQuKg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-color-rebeccapurple@11.0.0: resolution: {integrity: sha512-g9561mx7cbdqx7XeO/L+lJzVlzu7bICyXr72efBVKZGxIhvBBJf9fGXn3Cb6U4Bwh3LbzQO2e9NWBLVYdX5Eag==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-custom-media@12.0.1: resolution: {integrity: sha512-66syE14+VeqkUf0rRX0bvbTCbNRJF132jD+ceo8th1dap2YJEAqpdh5uG98CE3IbgHT7m9XM0GIlOazNWqQdeA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-custom-properties@15.0.1: resolution: {integrity: sha512-cuyq8sd8dLY0GLbelz1KB8IMIoDECo6RVXMeHeXY2Uw3Q05k/d1GVITdaKLsheqrHbnxlwxzSRZQQ5u+rNtbMg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-custom-selectors@9.0.1: resolution: {integrity: sha512-2XBELy4DmdVKimChfaZ2id9u9CSGYQhiJ53SvlfBvMTzLMW2VxuMb9rHsMSQw9kRq/zSbhT5x13EaK8JSmK8KQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-dir-pseudo-class@10.0.0: resolution: {integrity: sha512-DmtIzULpyC8XaH4b5AaUgt4Jic4QmrECqidNCdR7u7naQFdnxX80YI06u238a+ZVRXwURDxVzy0s/UQnWmpVeg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-double-position-gradients@7.0.1: resolution: {integrity: sha512-M69I4EolEGwiYa0KmxKWg4zZp2DxhlNM0Bz12OvHCj930GXDVCvFhdWNGsRscz6BIijN6tFryzSFsy8kMLyD5Q==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-easing-gradients@3.0.1: resolution: {integrity: sha512-UrOKb4cenjGmMmrheETw7Cjnn/IKn3xgTvHs92b0sSwMhKgeZKxJpduGRjYZ8wgpu3zOzzgQpRwOLhhtMofayA==} @@ -5500,24 +5498,24 @@ packages: resolution: {integrity: sha512-VG1a9kBKizUBWS66t5xyB4uLONBnvZLCmZXxT40FALu8EF0QgVZBYy5ApC0KhmpHsv+pvHMJHB3agKHwmocWjw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-focus-within@10.0.0: resolution: {integrity: sha512-dvql0fzUTG+gcJYp+KTbag5vAjuo94LDYZHkqDV1rnf5gPGer1v/SrmIZBdvKU8moep3HbcbujqGjzSb3DL53Q==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-font-variant@5.0.0: resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.5.10' postcss-gap-properties@7.0.0: resolution: {integrity: sha512-PSDF2QoZMRUbsINvXObQgxx4HExRP85QTT8qS/YN9fBsCPWCqUuwqAD6E6PNp0BqL/jU1eyWUBORaOK/J/9LDA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-html@1.8.1: resolution: {integrity: sha512-OLF6P7qctfAWayOhLpcVnTGqVeJzu2W3WpIYelfz2+JV5oGxfkcEvweN9U4XpeqE0P98dcD9ssusGwlF0TK0uQ==} @@ -5527,19 +5525,19 @@ packages: resolution: {integrity: sha512-rEGNkOkNusf4+IuMmfEoIdLuVmvbExGbmG+MIsyV6jR5UaWSoyPcAYHV/PxzVDCmudyF+2Nh/o6Ub2saqUdnuA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-lab-function@8.0.4: resolution: {integrity: sha512-dqcJSzVasdELD9xqJ1wfP95uzP57J6zFd80c7S3AWK127H9zwqR9Kbk5ZgyIfN2DiMStI7Vq8E7ablXNeTvpew==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-logical@9.0.0: resolution: {integrity: sha512-A4LNd9dk3q/juEUA9Gd8ALhBO3TeOeYurnyHLlf2aAToD94VHR8c5Uv7KNmf8YVRhTxvWsyug4c5fKtARzyIRQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} @@ -5548,47 +5546,47 @@ packages: resolution: {integrity: sha512-YGFOfVrjxYfeGTS5XctP1WCI5hu8Lr9SmntjfRC+iX5hCihEO+QZl9Ra+pkjqkgoVdDKvb2JccpElcowhZtzpw==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-opacity-percentage@3.0.0: resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} engines: {node: '>=18'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-overflow-shorthand@7.0.0: resolution: {integrity: sha512-9SLpjoUdGRoRrzoOdX66HbUs0+uDwfIAiXsRa7piKGOqPd6F4ZlON9oaDSP5r1Qpgmzw5L9Ht0undIK6igJPMA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-page-break@3.0.4: resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} peerDependencies: - postcss: ^8 + postcss: '>=8.5.10' postcss-place@11.0.0: resolution: {integrity: sha512-fAifpyjQ+fuDRp2nmF95WbotqbpjdazebedahXdfBxy5sHembOLpBQ1cHveZD9ZmjK26tYM8tikeNaUlp/KfHA==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-preset-env@11.3.0: resolution: {integrity: sha512-PpijTuY+NT35vvk7us0pw9lJVrsZZWukjONZsza2Kq1Gag8nrUXRkgdKdxyyhZPJ6R43L3/nLpspUK99TmU9xg==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-pseudo-class-any-link@11.0.0: resolution: {integrity: sha512-DNFZ4GMa3C3pU5dM+UCTG1CEeLtS1ZqV5DKSqCTJQMn1G5jnd/30fS8+A7H4o5bSD3MOcnx+VgI+xPE9Z5Wvig==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-replace-overflow-wrap@4.0.0: resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} peerDependencies: - postcss: ^8.0.3 + postcss: '>=8.5.10' postcss-resolve-nested-selector@0.1.6: resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==} @@ -5597,25 +5595,25 @@ packages: resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} engines: {node: '>=12.0'} peerDependencies: - postcss: ^8.3.3 + postcss: '>=8.5.10' postcss-safe-parser@7.0.1: resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} engines: {node: '>=18.0'} peerDependencies: - postcss: ^8.4.31 + postcss: '>=8.5.10' postcss-scss@4.0.9: resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} engines: {node: '>=12.0'} peerDependencies: - postcss: ^8.4.29 + postcss: '>=8.5.10' postcss-selector-not@9.0.0: resolution: {integrity: sha512-xhAtTdHnVU2M/CrpYOPyRUvg3njhVlKmn2GNYXDaRJV9Ygx4d5OkSkc7NINzjUqnbDFtaKXlISOBeyMXU/zyFQ==} engines: {node: '>=20.19.0'} peerDependencies: - postcss: ^8.4 + postcss: '>=8.5.10' postcss-selector-parser@7.1.1: resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} @@ -5624,7 +5622,7 @@ packages: postcss-sorting@8.0.2: resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==} peerDependencies: - postcss: ^8.4.20 + postcss: '>=8.5.10' postcss-value-parser@3.3.1: resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} @@ -5632,10 +5630,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@7.0.39: - resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} - engines: {node: '>=6.0.0'} - postcss@8.5.14: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} @@ -6318,7 +6312,7 @@ packages: resolution: {integrity: sha512-VkVD9r7jfUT/dq3mA3/I1WXXk2U71rO5wvU2yIil9PW5o1g3UM7Xc82vHmuVJHV7Y8ok5K137fmW5u3HbhtTOA==} engines: {node: '>=20'} peerDependencies: - postcss: ^8.3.3 + postcss: '>=8.5.10' stylelint: ^17.0.0 peerDependenciesMeta: postcss: @@ -6341,7 +6335,7 @@ packages: resolution: {integrity: sha512-uLJS6xgOCBw5EMsDW7Ukji8l28qRoMnkRch15s0qwZpskXvWt9oPzMmcYM307m9GN4MxuWLsQh4I6hU9yI53cQ==} engines: {node: '>=20'} peerDependencies: - postcss: ^8.3.3 + postcss: '>=8.5.10' stylelint: ^17.0.0 peerDependenciesMeta: postcss: @@ -12506,8 +12500,6 @@ snapshots: perfect-debounce@2.0.0: {} - picocolors@0.2.1: {} - picocolors@1.1.1: {} picomatch@2.3.2: {} @@ -12603,7 +12595,7 @@ snapshots: dependencies: chroma-js: 1.4.1 easing-coordinates: 2.0.2 - postcss: 7.0.39 + postcss: 8.5.14 postcss-value-parser: 3.3.1 postcss-focus-visible@11.0.0(postcss@8.5.14): @@ -12798,11 +12790,6 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@7.0.39: - dependencies: - picocolors: 0.2.1 - source-map: 0.6.1 - postcss@8.5.14: dependencies: nanoid: 3.3.11 From 553613163fbfdb5972a1b48301b7b01d35f37ae7 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 19 May 2026 17:12:18 +0200 Subject: [PATCH 075/313] fix(deps): bump @xmldom/xmldom to 0.8.13 --- desktop/pnpm-lock.yaml | 56 ++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/desktop/pnpm-lock.yaml b/desktop/pnpm-lock.yaml index aae2ca03a..cd660881c 100644 --- a/desktop/pnpm-lock.yaml +++ b/desktop/pnpm-lock.yaml @@ -168,10 +168,13 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@xmldom/xmldom@0.8.12': - resolution: {integrity: sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==} + '@xmldom/xmldom@0.8.13': + resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} - deprecated: this version has critical issues, please update to the latest version + + '@xmldom/xmldom@0.9.10': + resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} + engines: {node: '>=14.6'} abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} @@ -298,6 +301,10 @@ packages: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -1170,6 +1177,10 @@ packages: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} engines: {node: '>=10.4.0'} + plist@3.1.1: + resolution: {integrity: sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==} + engines: {node: '>=10.4.0'} + proc-log@5.0.0: resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} engines: {node: ^18.17.0 || >=20.5.0} @@ -1302,6 +1313,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + engines: {node: '>=10'} + hasBin: true + send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -1428,8 +1444,8 @@ packages: resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==} engines: {node: '>=18'} - tar@7.5.13: - resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + tar@7.5.15: + resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} engines: {node: '>=18'} temp-file@3.4.0: @@ -1642,7 +1658,7 @@ snapshots: fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 - plist: 3.1.0 + plist: 3.1.1 transitivePeerDependencies: - supports-color @@ -1683,7 +1699,7 @@ snapshots: dir-compare: 3.3.0 fs-extra: 9.1.0 minimatch: 10.2.5 - plist: 3.1.0 + plist: 3.1.1 transitivePeerDependencies: - supports-color @@ -1805,7 +1821,9 @@ snapshots: '@types/node': 24.10.9 optional: true - '@xmldom/xmldom@0.8.12': {} + '@xmldom/xmldom@0.8.13': {} + + '@xmldom/xmldom@0.9.10': {} abbrev@3.0.1: {} @@ -1875,8 +1893,8 @@ snapshots: minimatch: 10.2.5 read-config-file: 6.3.2 sanitize-filename: 1.6.4 - semver: 7.7.4 - tar: 7.5.13 + semver: 7.8.0 + tar: 7.5.15 temp-file: 3.4.0 transitivePeerDependencies: - supports-color @@ -2013,6 +2031,10 @@ snapshots: dependencies: balanced-match: 4.0.4 + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + buffer-crc32@0.2.13: {} buffer-equal@1.0.1: {} @@ -2875,7 +2897,7 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.6 minimist@1.2.8: {} @@ -3015,7 +3037,13 @@ snapshots: plist@3.1.0: dependencies: - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + plist@3.1.1: + dependencies: + '@xmldom/xmldom': 0.9.10 base64-js: 1.5.1 xmlbuilder: 15.1.1 @@ -3164,6 +3192,8 @@ snapshots: semver@7.7.4: {} + semver@7.8.0: {} + send@1.2.0: dependencies: debug: 4.4.3 @@ -3332,7 +3362,7 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - tar@7.5.13: + tar@7.5.15: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 From 3d6e5b5f6ba11d89bc3e822530e87edae7209d62 Mon Sep 17 00:00:00 2001 From: "Frederick [Bot]" Date: Wed, 20 May 2026 02:15:16 +0000 Subject: [PATCH 076/313] chore(i18n): update translations via Crowdin --- frontend/src/i18n/lang/el-GR.json | 517 +++++++++++++++++++++++++++++- 1 file changed, 513 insertions(+), 4 deletions(-) diff --git a/frontend/src/i18n/lang/el-GR.json b/frontend/src/i18n/lang/el-GR.json index 5083fb8d1..bb1b9b0f8 100644 --- a/frontend/src/i18n/lang/el-GR.json +++ b/frontend/src/i18n/lang/el-GR.json @@ -1,19 +1,189 @@ { + "404": { + "title": "Δε βρέθηκε", + "text": "Η σελίδα που ζητήσατε δεν υπάρχει." + }, "home": { "welcomeNight": "Καληνύχτα {username}!", "welcomeNightOwl": "Γεια σου νυχτερινή κουκουβάγια {username}", "welcomeNightBurning": "Κάνουμε υπερωρίες {username};", - "welcomeDayKeepGoing": "Συνέχισε, {username}" + "welcomeNightQuiet": "Ώρες ησυχίας, {username}", + "welcomeNightLate": "Είναι αργά, {username}", + "welcomeNightMoonlit": "Παράλληλη απασχόληση, {username};", + "welcomeMorning": "Καλημέρα {username}!", + "welcomeMorningHey": "Ε {username}, είσαι έτοιμος να ξεκινήσουμε;", + "welcomeMorningFresh": "Νέα αρχή, {username}", + "welcomeMorningCoffee": "Καφέ και εργασίες, {username};", + "welcomeMorningRise": "Ανεβάζουμε τα μανίκια, {username}", + "welcomeMorningBack": "Καλώς ήρθες και πάλι, {username}", + "welcomeMondayFresh": "Φρέσκια εβδομάδα, {username}", + "welcomeTuesday": "Χαρούμενη Τρίτη, {username}", + "welcomeWednesdayMid": "Ήδη είμαστε μεσοβδόμαδα, {username}", + "welcomeThursday": "Σχεδόν εκεί, {username}", + "welcomeFridayPush": "Γερά την Παρασκευή, {username};", + "welcomeSaturday": "Κατάσταση Σαββατοκύριακου, {username}", + "welcomeSundaySession": "Κυριακάτικη δουλίτσα, {username};", + "welcomeDay": "Γεια σου {username}!", + "welcomeDayBack": "Πίσω και πάλι, {username}", + "welcomeDayFocus": "Ας συγκεντρωθούμε, {username}", + "welcomeDayKeepGoing": "Συνέχισε, {username}", + "welcomeDayWhatsNext": "Τι έχει μετά, {username};", + "welcomeDayGood": "Καλό απόγευμα, {username}", + "welcomeEvening": "Καλησπέρα {username}!", + "welcomeEveningWind": "Χαλαρώνεις, {username};", + "welcomeEveningReturns": "Ο/Η {username} επιστρέφει", + "welcomeEveningWrap": "Ήρθε η ώρα να κλείσουμε, {username};", + "welcomeEveningOneMore": "Κάτι ακόμη, {username};", + "welcomeEveningStill": "Ακόμη σε αυτό, {username};", + "lastViewed": "Προβλήθηκε τελευταία", + "addToHomeScreen": "Προσθέστε την εφαρμογή στην αρχική οθόνη σας για ταχύτερη πρόσβαση και βελτιωμένη εμπειρία.", + "goToOverview": "Μετάβαση στην επισκόπηση", + "project": { + "importText": "Εισαγάγετε τα έργα και τις εργασίες σας από άλλες υπηρεσίες στο Vikunja:", + "import": "Εισαγωγή των δεδομένων σας στο Vikunja" + } + }, + "demo": { + "title": "Αυτή η εγκατάσταση βρίσκεται σε λειτουργία επίδειξης. Μην τη χρησιμοποιείτε με πραγματικά δεδομένα!", + "everythingWillBeDeleted": "Όλα θα διαγράφονται σε τακτά χρονικά διαστήματα!", + "accountWillBeDeleted": "Ο λογαριασμός σας θα διαγραφεί, συμπεριλαμβανομένων όλων των έργων, των εργασιών και των συνημμένων που ενδέχεται να είχατε δημιουργήσει." + }, + "ready": { + "loading": "Το Vikunja φορτώνει…", + "errorOccured": "Παρουσιάστηκε σφάλμα:", + "checkApiUrl": "Παρακαλώ ελέγξτε αν η διεύθυνση URL του API είναι σωστή.", + "noApiUrlConfigured": "Δεν έχει ρυθμιστεί διεύθυνση url για το API. Παρακαλώ ορίστε μία παρακάτω:" + }, + "offline": { + "title": "Είστε εκτός σύνδεσης.", + "text": "Ελέγξτε τη σύνδεση δικτύου σας και προσπαθήστε ξανά." }, "user": { "auth": { + "username": "Όνομα χρήστη", + "usernameEmail": "Όνομα Χρήστη ή Διεύθυνση Email", + "usernamePlaceholder": "π.χ. Φρειδερίκος", + "email": "Διεύθυνση email", + "emailPlaceholder": "π.χ. freiderikos{'@'}vikunja.io", + "password": "Κωδικός πρόσβασης", + "passwordPlaceholder": "π.χ. •••••••••••", + "forgotPassword": "Ξεχάσατε τον κωδικό σας πρόσβασης;", + "resetPassword": "Επαναφορά του κωδικού σας πρόσβασης", + "resetPasswordAction": "Να μου σταλεί σύνδεσμος επαναφοράς κωδικού πρόσβασης", + "resetPasswordSuccess": "Ελέγξτε τα εισερχόμενά σας! Θα πρέπει να έχετε λάβει ένα email με οδηγίες για την επαναφορά του κωδικού σας πρόσβασης.", + "confirmEmailSuccess": "Επιβεβαιώσατε με επιτυχία το email σας! Μπορείτε τώρα να συνδεθείτε.", + "totpTitle": "Κωδικός Ελέγχου Ταυτοποίησης Δύο Παραγόντων", + "totpPlaceholder": "π.χ. 123456", + "login": "Είσοδος", + "createAccount": "Δημιουργία λογαριασμού", + "loginWith": "Σύνδεση μέσω {provider}", + "authenticating": "Ταυτοποίηση…", + "openIdStateError": "Η κατάσταση δεν ταιριάζει, αρνούμαι να συνεχίσω!", + "openIdGeneralError": "Παρουσιάστηκε σφάλμα κατά την ταυτοποίηση μέσω τρίτου παρόχου.", "openIdTotpRequired": "Ο λογαριασμός σας απαιτεί ταυτοποίηση δύο παραγόντων. Εισαγάγετε τον κωδικό σας μίας χρήσης και κάνετε είσοδο εκ νέου.", + "openIdTotpSubmit": "Συνέχεια", + "oauthMissingParams": "Λείπουν οι απαιτούμενες παράμετροι OAuth: {params}", + "oauthRedirectedToApp": "Έχετε μεταβεί στην εφαρμογή. Μπορείτε να κλείσετε τώρα αυτή την καρτέλα.", + "desktopTryDemo": "Δοκιμάστε το demo", + "desktopCustomServer": "Προσαρμοσμένη Διεύθυνση URL Διακομιστή", + "desktopCustomServerDescription": "Εισαγάγετε τη διεύθυνση URL του διακομιστή σας Vikunja για να ξεκινήσετε.", "desktopWaitingForAuth": "Αναμονή για ταυτοποίηση…", - "desktopOAuthError": "Η ταυτοποίηση απέτυχε: {error}" + "desktopOAuthError": "Η ταυτοποίηση απέτυχε: {error}", + "logout": "Έξοδος", + "emailInvalid": "Παρακαλώ εισαγάγετε μια έγκυρη διεύθυνση email.", + "usernameRequired": "Παρακαλώ εισαγάγετε ένα όνομα χρήστη.", + "usernameMustNotContainSpace": "Το όνομα χρήστη δεν πρέπει να περιέχει κενούς χαρακτήρες.", + "usernameMustNotLookLikeUrl": "Το όνομα χρήστη δεν πρέπει να μοιάζει με URL.", + "passwordRequired": "Παρακαλώ εισαγάγετε ένα κωδικό πρόσβασης.", + "passwordNotMin": "Ο κωδικός πρόσβασης πρέπει να περιέχει τουλάχιστον 8 χαρακτήρες.", + "passwordNotMax": "Ο κωδικός πρόσβασης πρέπει να περιέχει το πολύ 72 χαρακτήρες.", + "showPassword": "Προβολή κωδικού πρόσβασης", + "hidePassword": "Απόκρυψη κωδικού πρόσβασης", + "noAccountYet": "Δεν έχετε ακόμη λογαριασμό;", + "alreadyHaveAnAccount": "Έχετε ήδη λογαριασμό;", + "remember": "Μείνετε συνδεδεμένος/η", + "registrationDisabled": "Η εγγραφή είναι απενεργοποιημένη.", + "passwordResetTokenMissing": "Λείπει το τεκμήριο επαναφοράς κωδικού πρόσβασης.", + "registrationFailed": "Παρουσιάστηκε σφάλμα κατά την εγγραφή. Παρακαλώ ελέγξτε τι εισαγάγατε και προσπαθήστε εκ νέου." }, "settings": { "bots": { - "description": "Οι χρήστες bot είναι μόνο API-χρήστες που εσείς κατέχετε. Μπορούν να προστεθούν σε έργα, ανατεθειμένες εργασίες και ταυτοποιούνται με τεκμήρια API. Δεν μπορούν να συνδεθούν διαδραστικά." + "title": "Χρήστες bot", + "description": "Οι χρήστες bot είναι μόνο API-χρήστες που εσείς κατέχετε. Μπορούν να προστεθούν σε έργα, ανατεθειμένες εργασίες και ταυτοποιούνται με τεκμήρια API. Δεν μπορούν να συνδεθούν διαδραστικά.", + "namePlaceholder": "Ο Βοηθός μου", + "create": "Δημιουργία bot", + "enable": "Ενεργοποίηση", + "badge": "Bot", + "delete": { + "header": "Διαγραφή αυτού του χρήστη bot", + "text1": "Είστε βέβαιοι ότι θέλετε να διαγράψετε τον χρήστη bot \"{username}\";", + "text2": "Αυτό είναι μη αναστρέψιμο. Οποιαδήποτε τεκμήρια API ανήκουν σε αυτό το bot θα ανακληθούν." + } + }, + "title": "Ρυθμίσεις", + "newPasswordTitle": "Ενημερώστε Τον Κωδικό σας Πρόσβασης", + "newPassword": "Νέος κωδικός πρόσβασης", + "currentPassword": "Τρέχων κωδικός πρόσβασης", + "currentPasswordPlaceholder": "Ο τρέχων κωδικός σας πρόσβασης", + "passwordUpdateSuccess": "Ο κωδικός πρόσβασης ενημερώθηκε με επιτυχία.", + "updateEmailTitle": "Ενημέρωση Της Διεύθυνσης Email σας", + "updateEmailNew": "Νέα διεύθυνση email", + "updateEmailSuccess": "Η διεύθυνση email σας ενημερώθηκε με επιτυχία. Έχει σταλεί ένας σύνδεσμος για να την επιβεβαιώσετε.", + "general": { + "title": "Γενικές Ρυθμίσεις", + "name": "Το Όνομά Μου", + "newName": "Το νέο όνομα", + "savedSuccess": "Οι ρυθμίσεις ενημερώθηκαν με επιτυχία.", + "emailReminders": "Να μου στέλνονται υπενθυμίσεις για τις εργασίες μέσω email", + "overdueReminders": "Να μου στέλνεται μια σύνοψη των καθυστερημένων και μη ολοκληρωμένων εργασιών κάθε μέρα", + "discoverableByName": "Να επιτρέπεται σε άλλους χρήστες να με προσθέτουν ως μέλος σε ομάδες ή έργα όταν ψάχνουν το όνομά μου", + "discoverableByEmail": "Να επιτρέπεται σε άλλους χρήστες να με προσθέτουν ως μέλος σε ομάδες ή έργα όταν ψάχνουν την πλήρη διεύθυνση email μου", + "playSoundWhenDone": "Να αναπαράγεται ένας ήχος όταν σημειώνονται οι εργασίες ως ολοκληρωμένες", + "allowIconChanges": "Να εμφανίζονται ειδικά λογότυπα σε συγκεκριμένες χρονικές περιόδους", + "alwaysShowBucketTaskCount": "Να εμφανίζεται πάντα ο αριθμός εργασιών στους κάδους Kanban", + "defaultTaskRelationType": "Προκαθορισμένος τύπος σχετιζόμενης εργασίας", + "weekStart": "Η εβδομάδα ξεκινάει την", + "weekStartSunday": "Κυριακή", + "weekStartMonday": "Δευτέρα", + "weekStartTuesday": "Τρίτη", + "weekStartWednesday": "Τετάρτη", + "weekStartThursday": "Πέμπτη", + "weekStartFriday": "Παρασκευή", + "weekStartSaturday": "Σάββατο", + "language": "Γλώσσα", + "defaultProject": "Προκαθορισμένο έργο", + "defaultView": "Προκαθορισμένη προβολή", + "timezone": "Ώρα ζώνης", + "overdueTasksRemindersTime": "Χρόνος υπενθύμισης με email εκπρόθεσμων εργασιών", + "quickAddDefaultReminders": "Προκαθορισμένες υπενθυμίσεις για γρήγορη προσθήκη", + "quickAddDefaultRemindersDescription": "Οι υπενθυμίσεις αυτές θα προστίθενται αυτόματα σε κάθε εργασία που δημιουργείται μέσω του quick add magic και περιέχει ημερομηνία παράδοσης.", + "quickAddDefaultRemindersHint": "Προσθέστε μία ή περισσότερες υπενθυμίσεις σχετικά με την ημερομηνία παράδοσης της εργασίας. Αφήστε κενό για απενεργοποίηση.", + "filterUsedOnOverview": "Αποθηκευμένο φίλτρο που χρησιμοποιείται στη σελίδα επισκόπησης", + "showLastViewed": "Εμφάνιση των τελευταία προβεβλημένων έργων στη σελίδα επισκόπησης", + "minimumPriority": "Ελάχιστη προτεραιότητα για ορατή εργασία", + "dateDisplay": "Μορφή εμφάνισης ημερομηνίας", + "dateDisplayOptions": { + "relative": "Σχετική (πχ. πριν από 3 ημέρες)", + "mm-dd-yyyy": "ΜΜ-ΗΗ-ΕΕΕΕ", + "dd-mm-yyyy": "ΗΗ-ΜΜ-ΕΕΕΕ", + "yyyy-mm-dd": "ΕΕΕΕ-ΜΜ-ΗΗ", + "mm/dd/yyyy": "ΜΜ/ΗΗ/ΕΕΕΕ", + "dd/mm/yyyy": "ΗΗ/ΜΜ/ΕΕΕΕ", + "yyyy/mm/dd": "ΕΕΕΕ/ΜΜ/ΗΗ" + }, + "timeFormat": "Μορφή ώρας", + "timeFormatOptions": { + "12h": "12 ώρες (ΠΜ/ΜΜ)", + "24h": "24 ώρες (ΩΩ:ΛΛ)" + }, + "externalUserNameChange": "Το όνομά σας διαχειρίζεται από τον πάροχό σας σύνδεσης ({provider}). Για να το αλλάξετε, ενημερώστε το εκεί." + }, + "sections": { + "personalInformation": "Προσωπικές Πληροφορίες", + "taskAndNotifications": "Έργα & Εργασίες", + "privacy": "Ιδιωτικότητα", + "localization": "Τοπική Προσαρμογή", + "appearance": "Εμφάνιση & Συμπεριφορά" }, "totp": { "title": "Ταυτοποίηση Δύο Παραγόντων", @@ -28,10 +198,191 @@ }, "feeds": { "apiTokenHint": "Ταυτοποιηθείτε με τεκμήριο API που έχει την άδεια {scope}. Δημιουργήστε ένα στο {link}." + }, + "apiTokens": { + "createToken": "Δημιουργία τεκμηρίου", + "30d": "30 Ημέρες", + "60d": "60 Ημέρες", + "90d": "90 Ημέρες", + "permissionExplanation": "Οι άδειες σας επιτρέπουν να ορίσετε την εμβέλεια του τι επιτρέπεται να κάνει ένα τεκμήριο api.", + "titleRequired": "Ο τίτλος είναι απαιτούμενος", + "permissionRequired": "Παρακαλώ επιλέξτε τουλάχιστον μια άδεια από τη λίστα.", + "expired": "Το τεκμήριο έχει λήξει {ago}.", + "tokenCreatedSuccess": "Αυτό είναι το νέο σας τεκμήριο api: {token}", + "tokenCreatedNotSeeAgain": "Αποθηκεύστε το σε μια ασφαλή τοποθεσία, διαφορετικά δε θα το ξαναδείτε!", + "presets": { + "title": "Γρήγορες προεπιλογές", + "readOnly": "Μόνο για ανάγνωση", + "tasks": "Διαχείριση εργασιών", + "projects": "Διαχείριση έργου", + "fullAccess": "Πλήρης πρόσβαση" + }, + "delete": { + "header": "Διαγραφή αυτού του τεκμηρίου", + "text1": "Είστε σίγουροι ότι θέλετε να διαγράψετε το τεκμήριο\"{token}\";", + "text2": "Αυτό θα ανακαλέσει την πρόσβαση σε όλες τις εφαρμογές ή ενσωματώσεις που το χρησιμοποιούν. Δεν μπορείτε να το αναιρέσετε." + }, + "attributes": { + "title": "Τίτλος", + "titlePlaceholder": "Εισαγάγετε έναν τίτλο που θα αναγνωρίζετε στο μέλλον", + "expiresAt": "Λήγει στις", + "permissions": "Άδειες" + } + }, + "sessions": { + "title": "Συνεδρίες", + "description": "Αυτές είναι όλες οι συσκευές που είναι συνδεδεμένες στον λογαριασμό σας. Μπορείτε να ανακαλέσετε οποιαδήποτε συνεδρία για να αποσυνδεθεί η συσκευή. Ενδέχεται να χρειαστούν έως και 10 λεπτά ώσπου η ανάκληση να τεθεί σε πλήρη ισχύ.", + "deviceInfo": "Συσκευή", + "ipAddress": "Διεύθυνση IP", + "lastActive": "Τελευταία Δραστηριότητα", + "current": "Τρέχουσα συνεδρία", + "delete": { + "header": "Ανάκληση συνεδρίας", + "text": "Είστε βέβαιοι ότι θέλετε να ανακαλέσετε αυτή τη συνεδρία; Η συσκευή θα αποσυνδεθεί. Μπορεί να χρειαστούν έως και 10 λεπτά για να λήξει πλήρως η συνεδρία." + }, + "deleteSuccess": "Η συνεδρία ανακλήθηκε επιτυχώς. Μπορεί να χρειαστούν έως και 10 λεπτά για να λήξει πλήρως.", + "noOtherSessions": "Δεν υπάρχουν άλλες ενεργές συνεδρίες." } + }, + "deletion": { + "title": "Διαγραφή του λογαριασμού σας Vikunja", + "text1": "Η διαγραφή του λογαριασμού σας είναι μόνιμη και δεν μπορεί να αναιρεθεί. Θα διαγράψουμε όλα τα έργα, τις εργασίες σας και όλα όσα σχετίζονται με αυτόν.", + "text2": "Για να συνεχίσετε, παρακαλώ εισαγάγετε τον κωδικό σας πρόσβασης. Θα λάβετε ένα email με περαιτέρω οδηγίες.", + "text3": "Για να συνεχίσετε, πατήστε το παρακάτω πλήκτρο. Θα λάβετε ένα email με περαιτέρω οδηγίες.", + "confirm": "Διαγραφή του λογαριασμού μου", + "requestSuccess": "Το αίτημα ήταν επιτυχές. Θα λάβετε ένα email με περαιτέρω οδηγίες.", + "passwordRequired": "Παρακαλώ εισαγάγετε τον κωδικό σας πρόσβασης.", + "confirmSuccess": "Έχετε επιβεβαιώσει με επιτυχία τη διαγραφή του λογαριασμού σας. Ο λογαριασμός σας θα διαγραφεί σε τρεις ημέρες.", + "scheduled": "Ο λογαριασμός σας στο Vikunja θα διαγραφεί στις {date} ({dateSince}).", + "scheduledCancel": "Για να ακυρώσετε τη διαγραφή του λογαριασμού σας, κάντε κλικ εδώ.", + "scheduledCancelText": "Για να ακυρώσετε τη διαγραφή του λογαριασμού σας, εισαγάγετε τον κωδικό σας πρόσβασης παρακάτω:", + "scheduledCancelButton": "Για να ακυρώσετε τη διαγραφή του λογαριασμού σας, πατήστε στο παρακάτω πλήκτρο:", + "scheduledCancelConfirm": "Ακύρωση της διαγραφής του λογαριασμού μου", + "scheduledCancelSuccess": "Δε θα διαγράψουμε τον λογαριασμό σας." + }, + "export": { + "title": "Εξαγωγή των δεδομένων σας από το Vikunja", + "description": "Μπορείτε να ζητήσετε αντίγραφο όλων των δεδομένων σας στο Vikunja. Αυτό περιλαμβάνει Έργα, Εργασίες και όλα όσα σχετίζονται με αυτά. Μπορείτε να εισαγάγετε αυτά τα δεδομένα σε οποιοδήποτε στιγμιότυπο Vikunja μέσω της λειτουργίας μετανάστευσης.", + "descriptionPasswordRequired": "Παρακαλώ εισαγάγετε τον κωδικό σας πρόσβασης για να συνεχίσετε:", + "request": "Ζητήστε αντίγραφο των δεδομένων σας στο Vikunja", + "success": "Έχετε αιτηθεί με επιτυχία τα δεδομένα σας στο Vikunja! Θα σας στείλουμε ένα email μόλις είναι έτοιμα για λήψη.", + "downloadTitle": "Κάντε λήψη των εξαχθέντων δεδομένων σας στο Vikunja", + "ready": "Η εξαγωγή σας είναι έτοιμη για λήψη. Μπορείτε να την κατεβάσετε μέχρι {0}.", + "requestNew": "Αίτηση για άλλη εξαγωγή" } }, "project": { + "archivedMessage": "Το έργο είναι αρχειοθετημένο. Δεν είναι δυνατό να δημιουργήσετε νέες εργασίες ή να επεξεργαστείτε εργασίες σε αυτό.", + "archived": "Αρχειοθετημένα", + "showArchived": "Προβολή αρχειοθετημένων", + "title": "Τίτλος", + "color": "Χρώμα", + "projects": "Έργα", + "parent": "Γονικό έργο", + "search": "Πληκτρολογήστε για αναζήτηση έργου…", + "searchSelect": "Κάντε κλικ ή πατήστε Enter για να επιλέξετε αυτό το έργο", + "shared": "Κοινόχρηστα Έργα", + "noDescriptionAvailable": "Δεν υπάρχει διαθέσιμη περιγραφή έργου.", + "inboxTitle": "Εισερχόμενα", + "favorite": "Να σημειωθεί το έργο ως αγαπημένο", + "unfavorite": "Αφαίρεση του έργου από τα αγαπημένα", + "openSettingsMenu": "Άνοιγμα μενού ρυθμίσεων έργου", + "description": "Περιγραφή έργου", + "favoriteDescription": "Το έργο έχει όλες τις εργασίες σημειωμένες στα αγαπημένα.", + "create": { + "header": "Νέο έργο", + "titlePlaceholder": "Ο τίτλος του έργου πηγαίνει εδώ…", + "addTitleRequired": "Παρακαλώ καθορίστε έναν τίτλο.", + "createdSuccess": "Το έργο δημιουργήθηκε με επιτυχία.", + "addProjectRequired": "Παρακαλώ καθορίστε ένα έργο ή επιλέξτε ένα έργο ως προεπιλεγμένο στις ρυθμίσεις." + }, + "archive": { + "title": "Αρχειοθέτηση του \"{project}\"", + "archive": "Αρχειοθέτηση του έργου", + "unarchive": "Κατάργηση αρχειοθέτησης του έργου", + "unarchiveText": "Θα μπορείτε να δημιουργήσετε εργασίες ή να τις επεξεργαστείτε.", + "archiveText": "Δε θα μπορείτε να επεξεργαστείτε το έργο ή να δημιουργήσετε εργασίες μέχρι να αναιρέσετε την αρχειοθέτησή του.", + "success": "Το έργο αρχειοθετήθηκε με επιτυχία." + }, + "background": { + "title": "Ορισμός φόντου έργου", + "remove": "Αφαίρεση φόντου", + "upload": "Επιλέξτε ένα φόντο από τον υπολογιστή σας", + "searchPlaceholder": "Αναζήτηση για φόντο…", + "poweredByUnsplash": "Με τη δύναμη του Unsplash", + "loadMore": "Φόρτωση περισσότερων φωτογραφιών", + "success": "Το φόντο έχει οριστεί με επιτυχία!", + "removeSuccess": "Το φόντο αφαιρέθηκε με επιτυχία!" + }, + "delete": { + "title": "Διαγραφή του \"{project}\"", + "header": "Διαγραφή του έργου", + "text1": "Είστε σίγουροι ότι θέλετε να διαγράψετε το έργο και όλο τα περιεχόμενό του;", + "text2": "Αυτό περιλαμβάνει όλες τις εργασίες και ΔΕΝ ΕΙΝΑΙ ΔΥΝΑΤΗ Η ΑΝΑΙΡΕΣΗ!", + "success": "Το έργο διαγράφηκε με επιτυχία.", + "tasksToDelete": "Αυτό θα αφαιρέσει οριστικά περίπου {count} εργασίες.", + "tasksAndChildProjectsToDelete": "Αυτό θα αφαιρέσει οριστικά περίπου {tasks} εργασίες και {projects} έργα." + }, + "first": { + "title": "Πρώτη Προβολή" + }, + "list": { + "title": "Λίστα", + "add": "Προσθήκη", + "addPlaceholder": "Προσθήκη εργασίας…", + "empty": "Το έργο είναι επί του παρόντος κενό.", + "newTaskCta": "Δημιουργήστε μια εργασία.", + "editTask": "Επεξεργασία Εργασίας", + "sort": "Ταξινόμηση" + }, + "gantt": { + "title": "Gantt", + "size": "Μέγεθος", + "default": "Προεπιλογή", + "month": "Μήνας", + "day": "Ημέρα", + "hour": "Ώρα", + "range": "Εύρος Ημερομηνιών", + "chartLabel": "Γράφημα Gantt Έργου", + "taskBarsForRow": "Μπάρες εργασίας για τη γραμμή {rowId}", + "taskBarLabel": "Εργασία: {task}. Από {startDate} έως {endDate}. {dateType}. Κάντε κλικ για επεξεργασία, σύρετε για μετακίνηση.", + "scheduledDates": "Προγραμματισμένες ημερομηνίες", + "estimatedDates": "Εκτιμώμενες ημερομηνίες", + "resizeStartDate": "Επανακαθορισμός ημερομηνίας έναρξης για την εργασία {task}", + "resizeEndDate": "Επανακαθορισμός ημερομηνίας λήξης για την εργασία {task}", + "timelineHeader": "Κεφαλίδα χρονοδιαγράμματος με μήνες και ημέρες", + "monthsRow": "Γραμμή μηνών", + "daysRow": "Γραμμή ημερών", + "monthLabel": "Μήνας: {month}", + "dayLabel": "Ημέρα: {date}, {weekday}", + "dayLabelToday": "Ημέρα: {date}, {weekday}", + "taskAriaLabel": "Εργασία: {task}", + "taskAriaLabelById": "Εργασία {id}", + "partialDatesStart": "Μόνο ημερομηνία έναρξης (ανοικτή λήξη)", + "partialDatesEnd": "Μόνο ημερομηνία λήξης (ανοικτή έναρξη)", + "expandGroup": "Ανάπτυξη της ομάδας: {task}", + "collapseGroup": "Σύμπτυξη της ομάδας: {task}", + "toggleRelationArrows": "Εναλλαγή βελών συσχέτισης" + }, + "table": { + "title": "Πίνακας", + "columns": "Στήλες" + }, + "kanban": { + "title": "Kanban", + "limit": "Όριο: {limit}", + "noLimit": "Δεν έχει οριστεί", + "doneBucket": "Κάδος για ολοκληρωμένα", + "doneBucketHint": "Όλες οι εργασίες που μετακινούνται σε αυτόν τον κάδο θα σημειώνονται αυτόματα ως ολοκληρωμένες.", + "doneBucketHintExtended": "Όλες οι εργασίες που μετακινούνται στον κάδο των ολοκληρωμένων θα σημειώνονται αυτόματα ως ολοκληρωμένες. Όλες οι εργασίες που σημειώνονται ως ολοκληρωμένες από αλλού επίσης θα μετακινηθούν.", + "doneBucketSavedSuccess": "Ο κάδος για τα ολοκληρωμένα αποθηκεύτηκε με επιτυχία.", + "defaultBucket": "Προκαθορισμένος κάδος", + "defaultBucketHint": "Όταν δημιουργείτε εργασίες χωρίς να καθορίσετε κάδο, θα προστίθενται σε αυτόν τον κάδο.", + "defaultBucketSavedSuccess": "Ο προκαθορισμένος κάδος αποθηκεύτηκε με επιτυχία.", + "deleteLast": "Δεν μπορείτε να αφαιρέσετε τον τελευταίο κάδο.", + "addTaskPlaceholder": "Εισαγάγετε τον τίτλο της νέας εργασίας…", + "addTask": "Προσθήκη εργασίας" + }, "webhooks": { "basicauthuser": "Χρήστης για Βασική Ταυτοποίηση", "basicauthpassword": "Κωδικός πρόσβασης για Βασική Ταυτοποίηση", @@ -83,6 +434,164 @@ "description": "Κάντε κλικ στο λογότυπο μιας από τις παρακάτω υπηρεσίες τρίτων για να ξεκινήσετε.", "descriptionDo": "Το Vikunja θα εισαγάγει όλες τις λίστες, εργασίες, σημειώσεις, υπενθυμίσεις και αρχεία που έχετε πρόσβαση.", "authorize": "Για να επιτρέψετε στο Vikunja να προσπελάσει το {name} Λογαριασμό σας, κάντε κλικ στο παρακάτω πλήκτρο.", - "alreadyMigrated1": "Φαίνεται ότι έχετε ήδη εισαγάγει τα στοιχεία σας από το {name} στο {date}." + "alreadyMigrated1": "Φαίνεται ότι έχετε ήδη εισαγάγει τα στοιχεία σας από το {name} στο {date}.", + "alreadyMigrated2": "Η εισαγωγή είναι και πάλι δυνατή, αλλά μπορεί να δημιουργήσει διπλότυπα. Είστε σίγουροι;", + "confirm": "Είμαι σίγουρος, παρακαλώ ξεκινήστε τη μετάβαση τώρα!", + "importUpload": "Για εισαγωγή δεδομένων από το {name} στο Vikunja, κάντε κλικ στο παρακάτω κουμπί για να επιλέξετε ένα αρχείο.", + "migrationStartedWillReciveEmail": "Το Vikunja θα εισάγει τώρα λίστες/έργα, εργασίες, σημειώσεις, υπενθυμίσεις και αρχεία από το {service}. Καθώς αυτό ενδέχεται να διαρκέσει λίγο χρόνο, θα σας σταλεί ένα email μόλις ολοκληρωθεί. Μπορείτε να κλείσετε τώρα το παράθυρο του προγράμματος πλοήγησης.", + "migrationInProgress": "Μια μετάβαση βρίσκεται σε εξέλιξη αυτήν τη στιγμή. Παρακαλώ περιμένετε μέχρι να ολοκληρωθεί.", + "csv": { + "description": "Εισαγωγή εργασιών από ένα αρχείο CSV με προσαρμοσμένη αντιστοίχιση στηλών.", + "uploadDescription": "Επιλέξτε ένα αρχείο CSV για εισαγωγή. Το αρχείο πρέπει να περιέχει τα δεδομένα των εργασιών με κεφαλίδες στην πρώτη γραμμή.", + "columnMappingDescription": "Αντιστοίχιση κάθε στήλης στο αρχείο CSV με ιδιότητα εργασίας. Το Vikunja έχει εντοπίσει αυτόματα τις πιο πιθανές αντιστοιχίσεις. Η παρακάτω προεπισκόπηση θα ενημερωθεί αυτόματα όταν αλλάζετε τις ρυθμίσεις.", + "parsingOptions": "Επιλογές Ανάλυσης" + } + }, + "label": { + "description": "Κάντε κλικ σε μια ετικέτα για να την επεξεργαστείτε. Μπορείτε να επεξεργαστείτε όλες τις ετικέτες που δημιουργήσατε, μπορείτε να χρησιμοποιήσετε όλες τις ετικέτες που σχετίζονται με μια εργασία σε έργο στο οποίο έχετε πρόσβαση." + }, + "sharing": { + "passwordRequired": "Αυτό το διαμοιραζόμενο έργο απαιτεί έναν κωδικό πρόσβασης. Παρακαλώ εισάγετέ τον παρακάτω:", + "projectLoadError": "Αποτυχία φόρτωσης πληροφοριών έργου." + }, + "navigation": { + "imprint": "Αποτύπωμα" + }, + "misc": { + "skipToContent": "Μετάβαση στο κύριο περιεχόμενο" + }, + "input": { + "editor": { + "codeTooltip": "Καταγράψτε ένα απόσπασμα κώδικα.", + "quoteTooltip": "Καταγράψτε μια φράση.", + "bulletListTooltip": "Δημιουργήστε μια απλή λίστα κουκκίδων.", + "orderedList": "Ταξινομημένη λίστα", + "orderedListTooltip": "Δημιουργήστε μια λίστα με αρίθμηση.", + "taskListTooltip": "Παρακολουθήστε εργασίες με μια to-do λίστα.", + "placeholder": "Πληκτρολογήστε κάποιο κείμενο ή πατήστε '/' για να δείτε περισσότερες επιλογές…" + }, + "multiselect": { + "selectPlaceholder": "Κάντε κλικ ή πατήστε enter για να επιλέξετε" + }, + "datepickerRange": { + "values": { + "startOfToday": "Έναρξη της ημέρας", + "endOfToday": "Τέλος της ημέρας", + "beginningOflastWeek": "Αρχή της προηγούμενης εβδομάδας" + } + }, + "datemathHelp": { + "canuse": "Μπορείτε να χρησιμοποιήσετε μαθηματικά σε ημερομηνίες για σχετικές ημερομηνίες.", + "title": "Μαθηματικά Ημερομηνιών", + "intro": "Καθορίστε σχετικές ημερομηνίες που επιλύονται στη στιγμή από το Vikunja κατά την εφαρμογή του φίλτρου.", + "expression": "Κάθε μαθηματική έκφραση ημερομηνίας ξεκινά με μια ημερομηνία αγκύρωσης, η οποία μπορεί να είναι είτε {0}, ή μια συμβολοσειρά ημερομηνίας που τελειώνει σε {1}. Αυτή η ημερομηνία αγκύρωσης μπορεί προαιρετικά να ακολουθείται από μία ή περισσότερες εκφράσεις μαθηματικών.", + "similar": "Αυτές οι εκφράσεις είναι παρόμοιες με αυτές που παρέχονται από {0} και {1}." + } + }, + "task": { + "detail": { + "actions": { + "percentDone": "Ορισμός Προόδου", + "attachments": "Προσθήκη Συνημμένων", + "relatedTasks": "Προσθήκη Συσχέτισης", + "moveProject": "Μετακίνηση", + "duplicate": "Αντιγραφή", + "color": "Ορισμός Χρώματος", + "delete": "Διαγραφή", + "favorite": "Προσθήκη στα Αγαπημένα", + "unfavorite": "Αφαίρεση από τα Αγαπημένα" + } + }, + "attributes": { + "assignees": "Ανατιθέμενοι", + "color": "Χρώμα", + "created": "Δημιουργήθηκε", + "createdBy": "Δημιουργήθηκε Από", + "description": "Περιγραφή", + "done": "Ολοκληρώθηκε", + "endDate": "Ημερομηνία Λήξης", + "labels": "Ετικέτες", + "percentDone": "Πρόοδος", + "priority": "Προτεραιότητα", + "project": "Έργο", + "relatedTasks": "Σχετιζόμενες Εργασίες", + "reminders": "Υπενθυμίσεις", + "repeat": "Επανάληψη", + "comment": "{count} σχόλιο | {count} σχόλια", + "commentCount": "Αριθμός σχολίων", + "startDate": "Ημερομηνία Έναρξης", + "title": "Τίτλος", + "updated": "Ενημερώθηκε", + "doneAt": "Ολοκληρώθηκε Στις" + }, + "subscription": { + "subscribedTaskThroughParentProject": "Δεν μπορείτε να κάνετε απεγγραφή εδώ επειδή έχετε εγγραφεί σε αυτήν την εργασία μέσω του έργου της.", + "subscribedProject": "Αυτή τη στιγμή είστε εγγεγραμμένοι σε αυτό το έργο και θα λαμβάνετε ειδοποιήσεις για αλλαγές.", + "notSubscribedProject": "Δεν είστε εγγεγραμμένοι σε αυτό το έργο και δε θα λαμβάνετε ειδοποιήσεις για αλλαγές.", + "subscribedTask": "Αυτή τη στιγμή είστε εγγεγραμμένοι σε αυτήν την εργασία και θα λαμβάνετε ειδοποιήσεις για αλλαγές.", + "notSubscribedTask": "Δεν είστε εγγεγραμμένοι σε αυτή την εργασία και δε θα λαμβάνετε ειδοποιήσεις για αλλαγές.", + "subscribe": "Εγγραφή", + "unsubscribe": "Απεγγραφή", + "subscribeSuccessProject": "Είστε τώρα εγγεγραμμένοι στο έργο", + "unsubscribeSuccessProject": "Έχετε κάνει απεγγραφή από το έργο", + "subscribeSuccessTask": "Είστε τώρα εγγεγραμμένοι στην εργασία", + "unsubscribeSuccessTask": "Έχετε κάνει απεγγραφή από την εργασία" + }, + "attachment": { + "deleteText1": "Είστε σίγουροι ότι θέλετε να διαγράψετε το συνημμένο {filename};", + "copyUrlTooltip": "Αντιγραφή της διεύθυνσης url του συνημμένου για χρήση σε κείμενο", + "setAsCover": "Δημιουργία καλύμματος", + "unsetAsCover": "Αφαίρεση καλύμματος", + "successfullyChangedCoverImage": "Η εικόνα καλύμματος τροποποιήθηκε με επιτυχία." + }, + "label": { + "addCreateSuccess": "Η ετικέτα δημιουργήθηκε και προστέθηκε με επιτυχία.", + "delete": { + "header": "Διαγραφή της ετικέτας", + "text1": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτή την ετικέτα;", + "text2": "Αυτό θα το αφαιρέσει από όλες τις εργασίες και δεν μπορεί να αναιρεθεί." + } + }, + "priority": { + "doNow": "ΝΑ ΓΙΝΕΙ ΤΩΡΑ" + }, + "relation": { + "add": "Προσθήκη Νέας Συσχέτισης Εργασίας", + "new": "Νέα Συσχέτιση Εργασίας", + "searchPlaceholder": "Πληκτρολογήστε στην αναζήτηση μια εργασία για να την προσθέσετε ως σχετιζόμενη…", + "createPlaceholder": "Προσθέστε την ως σχετιζόμενη εργασία", + "differentProject": "Η εργασία ανήκει σε διαφορετικό έργο.", + "noneYet": "Δεν υπάρχουν ακόμη συσχετίσεις.", + "delete": "Διαγραφή Συσχέτισης Εργασίας", + "deleteText1": "Είστε σίγουροι ότι θέλετε να διαγράψετε τη συσχέτιση εργασίας;", + "select": "Επιλέξτε είδος σχέσης" + }, + "reminder": { + "before": "{amount} {unit} πριν {type}", + "after": "{amount} {unit} μετά {type}", + "afterShort": "μετά", + "onStartDate": "Στην ημερομηνία έναρξης", + "onEndDate": "Στην ημερομηνία λήξης", + "custom": "Προσαρμογή", + "dateAndTime": "Ημερομηνία και ώρα" + }, + "repeat": { + "everyDay": "Κάθε Ημέρα", + "everyWeek": "Κάθε Εβδομάδα", + "every30d": "Κάθε 30 Ημέρες", + "mode": "Λειτουργία επανάληψης", + "monthly": "Μηνιαία", + "fromCurrentDate": "Από την ημερομηνία ολοκλήρωσης", + "each": "Κάθε", + "specifyAmount": "Καθορίστε μια τιμή…", + "hours": "Ώρες", + "days": "Ημέρες", + "weeks": "Εβδομάδες", + "invalidAmount": "Παρακαλώ εισαγάγετε μια τιμή μεγαλύτερη από το 0." + }, + "quickAddMagic": { + "quickEntryHint": "Χρήση μαγικών προθεμάτων για ημερομηνίες, ετικέτες & άλλα. Ανοίξτε την κύρια εφαρμογή Vikunja και ελέγξτε την υπόδειξη στην είσοδο εργασίας για περισσότερες λεπτομέρειες.", + "title": "Κατάσταση Quick Add Magic" + } } } \ No newline at end of file From 44db02ab56651e26e4383ffc1d49fcdc812bf0d5 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 20 May 2026 17:39:11 +0200 Subject: [PATCH 077/313] fix(task): print styles --- frontend/src/components/misc/Modal.vue | 2 +- frontend/src/components/tasks/partials/Heading.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/misc/Modal.vue b/frontend/src/components/misc/Modal.vue index f33dd5aac..8d81eb3b5 100644 --- a/frontend/src/components/misc/Modal.vue +++ b/frontend/src/components/misc/Modal.vue @@ -17,7 +17,7 @@ > diff --git a/frontend/src/components/tasks/partials/Heading.vue b/frontend/src/components/tasks/partials/Heading.vue index 4695820c6..7b513684e 100644 --- a/frontend/src/components/tasks/partials/Heading.vue +++ b/frontend/src/components/tasks/partials/Heading.vue @@ -18,7 +18,7 @@ @@ -39,7 +39,7 @@ From 612628a6570c583443fe23cef48818de5ba706f9 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 20 May 2026 17:53:01 +0200 Subject: [PATCH 078/313] fix(modal): print full content of modal dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A opened via showModal() lives in the browser's top layer, which renders only on the first page during print — top-layer elements are viewport-anchored and don't paginate. CSS overrides like position: static have no effect since top-layer membership is browser-managed. Swap to a non-modal dialog on beforeprint (removes it from the top layer so content flows in normal document order) and back to modal on afterprint. The accompanying @media print rules reset the dialog's fixed positioning and overflow so the non-modal dialog can paginate freely. --- frontend/src/components/misc/Modal.vue | 60 +++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/misc/Modal.vue b/frontend/src/components/misc/Modal.vue index 8d81eb3b5..5a3fedc98 100644 --- a/frontend/src/components/misc/Modal.vue +++ b/frontend/src/components/misc/Modal.vue @@ -62,7 +62,7 @@ @@ -361,6 +394,31 @@ $modal-width: 1024px; } } +// Unconstrain the native so the full modal content flows onto the +// printed page instead of being clipped to the viewport-sized top layer. +@media print { + .modal-dialog { + position: static; + inline-size: auto; + block-size: auto; + max-inline-size: none; + max-block-size: none; + + &::backdrop { + display: none; + } + } + + .modal-container { + overflow: visible; + min-block-size: 0; + } + + :deep(.card) { + min-block-size: 0 !important; + } +} + .modal-content:has(.modal-header) { display: flex; flex-direction: column; From bc7c2059aaa79c00f738322829ffbd26c901d340 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 20 May 2026 17:54:15 +0200 Subject: [PATCH 079/313] fix(print): hide bucket select icon --- frontend/src/components/tasks/partials/BucketSelect.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/tasks/partials/BucketSelect.vue b/frontend/src/components/tasks/partials/BucketSelect.vue index 72e33c58a..937527b2a 100644 --- a/frontend/src/components/tasks/partials/BucketSelect.vue +++ b/frontend/src/components/tasks/partials/BucketSelect.vue @@ -11,7 +11,7 @@ {{ currentBucketTitle }} From 995aad3d5338bd6c2032e73b1d1e5d28f40982dc Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 20 May 2026 17:58:13 +0200 Subject: [PATCH 080/313] fix(print): hide description editor when no description is present --- frontend/src/components/tasks/partials/Description.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/tasks/partials/Description.vue b/frontend/src/components/tasks/partials/Description.vue index 7b5ab3907..10bc3c9ce 100644 --- a/frontend/src/components/tasks/partials/Description.vue +++ b/frontend/src/components/tasks/partials/Description.vue @@ -1,5 +1,7 @@