You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2025/02/13 10:37:07 UTC

(skywalking-banyandb) branch main updated: Add backup and restore binaries into docker image (#607)

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


The following commit(s) were added to refs/heads/main by this push:
     new 55224870 Add backup and restore binaries into docker image (#607)
55224870 is described below

commit 552248704797a97decf505c3e53bb6fa1c58fb4e
Author: Gao Hongtao <ha...@gmail.com>
AuthorDate: Thu Feb 13 18:37:02 2025 +0800

    Add backup and restore binaries into docker image (#607)
    
    * Refactor backup directory
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
    
    * Bump up go tool chain
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
    
    * Format ui
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
    
    ---------
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
---
 Makefile                                           |   2 +-
 banyand/Dockerfile                                 |   4 +
 banyand/Makefile                                   |   2 +-
 {bydbbackup/pkg => banyand/backup}/backup.go       |  57 ++-
 {bydbbackup/pkg => banyand/backup}/backup_test.go  |   5 +-
 {bydbbackup/pkg => banyand/backup}/restore.go      |  26 +-
 {bydbbackup/pkg => banyand/backup}/restore_test.go |  11 +-
 {bydbbackup/pkg => banyand/backup}/timedir.go      |  23 +-
 {bydbbackup/pkg => banyand/backup}/timedir_test.go |  45 +-
 {bydbbackup => banyand}/cmd/backup/main.go         |   4 +-
 {bydbbackup => banyand}/cmd/restore/main.go        |   4 +-
 banyand/internal/storage/segment.go                |   4 +-
 banyand/internal/storage/shard.go                  |   2 +-
 banyand/internal/storage/snapshot.go               |   2 +-
 banyand/internal/storage/storage.go                |   9 +-
 banyand/internal/storage/tsdb.go                   |  13 +-
 banyand/measure/block_writer.go                    |  15 +-
 banyand/measure/part.go                            |  15 +-
 banyand/measure/part_metadata.go                   |   3 +-
 banyand/measure/service.go                         |   7 +-
 banyand/measure/snapshot.go                        |   6 +-
 banyand/measure/tstable.go                         |   5 +-
 banyand/property/db.go                             |   9 +-
 banyand/property/listener.go                       |   6 +-
 banyand/property/service.go                        |   6 +-
 banyand/stream/block_writer.go                     |  13 +-
 banyand/stream/part.go                             |  13 +-
 banyand/stream/part_metadata.go                    |   3 +-
 banyand/stream/service.go                          |   7 +-
 banyand/stream/snapshot.go                         |   8 +-
 banyand/stream/tstable.go                          |   5 +-
 bydbbackup/Makefile                                |  34 --
 dist/LICENSE                                       | 126 +++---
 dist/licenses/ui-licenses/license-sass.txt         |  36 +-
 docs/operation/backup.md                           |   6 +-
 docs/operation/restore.md                          |   4 +-
 go.mod                                             |  92 ++--
 go.sum                                             | 186 ++++----
 scripts/build/build.mk                             |   2 +-
 scripts/build/version.mk                           |   2 +-
 scripts/ci/check/version_test.go                   |   2 +-
 test/cases/backup/all.go                           |  14 +-
 test/cases/backup/backup.go                        |   4 +-
 ui/LICENSE                                         |  36 +-
 ui/package-lock.json                               | 467 +++++++++++----------
 ui/src/styles/custom.scss                          |   4 +-
 46 files changed, 682 insertions(+), 667 deletions(-)

diff --git a/Makefile b/Makefile
index 66974133..0d6a1747 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ endif
 
 include scripts/build/version.mk
 
-PROJECTS := ui banyand bydbctl bydbbackup
+PROJECTS := ui banyand bydbctl
 
 TEST_CI_OPTS ?=
 
diff --git a/banyand/Dockerfile b/banyand/Dockerfile
index 5f21348f..bbac3f3d 100644
--- a/banyand/Dockerfile
+++ b/banyand/Dockerfile
@@ -24,6 +24,8 @@ ARG TARGETARCH
 ARG BINARYTYPE
 
 COPY build/bin/linux/${TARGETARCH}/banyand-server-${BINARYTYPE} /banyand
+COPY build/bin/linux/${TARGETARCH}/banyand-backup-${BINARYTYPE} /backup
+COPY build/bin/linux/${TARGETARCH}/banyand-restore-${BINARYTYPE} /restore
 COPY --from=certs /etc/ssl/certs /etc/ssl/certs
 
 FROM mcr.microsoft.com/windows/servercore:ltsc2022 AS build-windows
@@ -31,6 +33,8 @@ FROM mcr.microsoft.com/windows/servercore:ltsc2022 AS build-windows
 ARG TARGETARCH
 
 COPY build/bin/windows/${TARGETARCH}/banyand-server-static "/banyand"
+COPY build/bin/windows/${TARGETARCH}/banyand-backup-static "/backup"
+COPY build/bin/windows/${TARGETARCH}/banyand-restore-static "/restore"
 
 FROM build-${TARGETOS} AS final
 
diff --git a/banyand/Makefile b/banyand/Makefile
index f39cf0ee..6cf1953b 100644
--- a/banyand/Makefile
+++ b/banyand/Makefile
@@ -17,7 +17,7 @@
 #
 
 NAME := banyand
-BINARIES := $(NAME)-server
+BINARIES := $(NAME)-server $(NAME)-backup $(NAME)-restore
 
 IMG_NAME := skywalking-banyandb
 
diff --git a/bydbbackup/pkg/backup.go b/banyand/backup/backup.go
similarity index 88%
rename from bydbbackup/pkg/backup.go
rename to banyand/backup/backup.go
index 484ce83a..e8ed8003 100644
--- a/bydbbackup/pkg/backup.go
+++ b/banyand/backup/backup.go
@@ -15,8 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// Package pkg provides the backup command-line tool.
-package pkg
+// Package backup provides the backup command-line tool.
+package backup
 
 import (
 	"context"
@@ -37,6 +37,8 @@ import (
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
+	"github.com/apache/skywalking-banyandb/pkg/config"
 	"github.com/apache/skywalking-banyandb/pkg/fs/remote"
 	"github.com/apache/skywalking-banyandb/pkg/fs/remote/local"
 	"github.com/apache/skywalking-banyandb/pkg/grpchelper"
@@ -45,46 +47,38 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/version"
 )
 
-const snapshotDir = "snapshots"
-
-var scheduleExprMap = map[string]string{
-	"hourly": "5 * * * *",
-	"daily":  "5 0 * * *",
-}
-
 // NewBackupCommand creates a new backup command.
 func NewBackupCommand() *cobra.Command {
 	var (
-		gRPCAddr      string
-		enableTLS     bool
-		insecure      bool
-		cert          string
-		streamRoot    string
-		measureRoot   string
-		propertyRoot  string
-		dest          string
-		timeStyle     string
-		scheduleStyle string
+		gRPCAddr     string
+		enableTLS    bool
+		insecure     bool
+		cert         string
+		streamRoot   string
+		measureRoot  string
+		propertyRoot string
+		dest         string
+		timeStyle    string
+		schedule     string
 	)
 
 	cmd := &cobra.Command{
 		Short:             "Backup BanyanDB snapshots to remote storage",
 		DisableAutoGenTag: true,
 		Version:           version.Build(),
-		RunE: func(_ *cobra.Command, _ []string) error {
-			if scheduleStyle == "" {
+		RunE: func(cmd *cobra.Command, _ []string) error {
+			if err := config.Load("logging", cmd.Flags()); err != nil {
+				return err
+			}
+			if schedule == "" {
 				return backupAction(dest, gRPCAddr, enableTLS, insecure, cert,
 					streamRoot, measureRoot, propertyRoot, timeStyle)
 			}
-			expr, ok := scheduleExprMap[scheduleStyle]
-			if !ok {
-				return fmt.Errorf("unsupported schedule style: %s. Only support: hourly or daily", scheduleStyle)
-			}
 			schedLogger := logger.GetLogger().Named("backup-scheduler")
+			schedLogger.Info().Msgf("backup to %s will run with schedule: %s", dest, schedule)
 			clockInstance := clock.New()
 			sch := timestamp.NewScheduler(schedLogger, clockInstance)
-			cronOptions := cron.Minute | cron.Hour
-			err := sch.Register("backup", cronOptions, expr, func(_ time.Time, l *logger.Logger) bool {
+			err := sch.Register("backup", cron.Descriptor, schedule, func(_ time.Time, l *logger.Logger) bool {
 				err := backupAction(dest, gRPCAddr, enableTLS, insecure, cert,
 					streamRoot, measureRoot, propertyRoot, timeStyle)
 				if err != nil {
@@ -117,7 +111,12 @@ func NewBackupCommand() *cobra.Command {
 	cmd.Flags().StringVar(&propertyRoot, "property-root-path", "/tmp", "Root directory for property catalog")
 	cmd.Flags().StringVar(&dest, "dest", "", "Destination URL (e.g., file:///backups)")
 	cmd.Flags().StringVar(&timeStyle, "time-style", "daily", "Time directory style (daily|hourly)")
-	cmd.Flags().StringVar(&scheduleStyle, "schedule", "", "Schedule expression for periodic backup. The format is a cron expression \"<minute> <hour>\"")
+	cmd.Flags().StringVar(
+		&schedule,
+		"schedule",
+		"",
+		"Schedule expression for periodic backup. Options: @yearly, @monthly, @weekly, @daily, @hourly or @every <duration>",
+	)
 
 	return cmd
 }
@@ -199,7 +198,7 @@ func getSnapshotDir(snapshot *databasev1.Snapshot, streamRoot, measureRoot, prop
 	default:
 		return "", errors.New("unknown catalog type")
 	}
-	return filepath.Join(baseDir, snapshotDir, snapshot.Name), nil
+	return filepath.Join(baseDir, storage.SnapshotsDir, snapshot.Name), nil
 }
 
 func getTimeDir(style string) string {
diff --git a/bydbbackup/pkg/backup_test.go b/banyand/backup/backup_test.go
similarity index 97%
rename from bydbbackup/pkg/backup_test.go
rename to banyand/backup/backup_test.go
index 64759955..8d9bd5d3 100644
--- a/bydbbackup/pkg/backup_test.go
+++ b/banyand/backup/backup_test.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package pkg
+package backup
 
 import (
 	"context"
@@ -28,6 +28,7 @@ import (
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 )
 
 func TestNewFS(t *testing.T) {
@@ -64,7 +65,7 @@ func TestGetSnapshotDir(t *testing.T) {
 			"stream catalog",
 			&databasev1.Snapshot{Catalog: commonv1.Catalog_CATALOG_STREAM, Name: "test"},
 			"/tmp", "/tmp", "/tmp",
-			filepath.Join("/tmp/stream", snapshotDir, "test"),
+			filepath.Join("/tmp/stream", storage.SnapshotsDir, "test"),
 			false,
 		},
 		{
diff --git a/bydbbackup/pkg/restore.go b/banyand/backup/restore.go
similarity index 89%
rename from bydbbackup/pkg/restore.go
rename to banyand/backup/restore.go
index 141d94bb..fab184c9 100644
--- a/bydbbackup/pkg/restore.go
+++ b/banyand/backup/restore.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package pkg
+package backup
 
 import (
 	"context"
@@ -30,22 +30,22 @@ import (
 	"go.uber.org/multierr"
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
+	"github.com/apache/skywalking-banyandb/pkg/config"
 	"github.com/apache/skywalking-banyandb/pkg/fs/remote"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
 	"github.com/apache/skywalking-banyandb/pkg/version"
 )
 
-const (
-	dirPerm = 0o755
-	dataDir = "data"
-)
-
 // NewRestoreCommand creates a new restore command.
 func NewRestoreCommand() *cobra.Command {
 	rootCmd := &cobra.Command{
 		DisableAutoGenTag: true,
 		Version:           version.Build(),
 		Short:             "Restore BanyanDB data from remote storage",
+		PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
+			return config.Load("logging", cmd.Flags())
+		},
 	}
 	rootCmd.AddCommand(newRunCommand())
 	rootCmd.AddCommand(NewTimeDirCommand())
@@ -78,7 +78,7 @@ func newRunCommand() *cobra.Command {
 			var errs error
 
 			if streamRoot != "" {
-				timeDirPath := filepath.Join(streamRoot, "stream-time-dir")
+				timeDirPath := filepath.Join(streamRoot, "stream", "time-dir")
 				if data, err := os.ReadFile(timeDirPath); err == nil {
 					timeDir := strings.TrimSpace(string(data))
 					if err = restoreCatalog(fs, timeDir, streamRoot, commonv1.Catalog_CATALOG_STREAM); err != nil {
@@ -91,7 +91,7 @@ func newRunCommand() *cobra.Command {
 				}
 			}
 			if measureRoot != "" {
-				timeDirPath := filepath.Join(measureRoot, "measure-time-dir")
+				timeDirPath := filepath.Join(measureRoot, "measure", "time-dir")
 				if data, err := os.ReadFile(timeDirPath); err == nil {
 					timeDir := strings.TrimSpace(string(data))
 					if err = restoreCatalog(fs, timeDir, measureRoot, commonv1.Catalog_CATALOG_MEASURE); err != nil {
@@ -104,7 +104,7 @@ func newRunCommand() *cobra.Command {
 				}
 			}
 			if propertyRoot != "" {
-				timeDirPath := filepath.Join(propertyRoot, "property-time-dir")
+				timeDirPath := filepath.Join(propertyRoot, "property", "time-dir")
 				if data, err := os.ReadFile(timeDirPath); err == nil {
 					timeDir := strings.TrimSpace(string(data))
 					if err = restoreCatalog(fs, timeDir, propertyRoot, commonv1.Catalog_CATALOG_PROPERTY); err != nil {
@@ -136,11 +136,13 @@ func restoreCatalog(fs remote.FS, timeDir, rootPath string, catalog commonv1.Cat
 		return fmt.Errorf("failed to list remote files: %w", err)
 	}
 
-	localDir := filepath.Join(getLocalDir(rootPath, catalog), dataDir)
-	if err = os.MkdirAll(localDir, dirPerm); err != nil {
+	localDir := filepath.Join(getLocalDir(rootPath, catalog), storage.DataDir)
+	if err = os.MkdirAll(localDir, storage.DirPerm); err != nil {
 		return fmt.Errorf("failed to create local directory %s: %w", localDir, err)
 	}
 
+	logger.Infof("Restoring %s to %s from %s", getCatalogName(catalog), localDir, remotePrefix)
+
 	remoteRelSet := make(map[string]bool)
 	var relPath string
 	for _, remoteFile := range remoteFiles {
@@ -175,7 +177,7 @@ func restoreCatalog(fs remote.FS, timeDir, rootPath string, catalog commonv1.Cat
 		localPath := filepath.Join(rootPath, relPath)
 
 		if !contains(localFiles, relPath) {
-			if err := os.MkdirAll(filepath.Dir(localPath), dirPerm); err != nil {
+			if err := os.MkdirAll(filepath.Dir(localPath), storage.DirPerm); err != nil {
 				return fmt.Errorf("failed to create directory for %s: %w", localPath, err)
 			}
 
diff --git a/bydbbackup/pkg/restore_test.go b/banyand/backup/restore_test.go
similarity index 88%
rename from bydbbackup/pkg/restore_test.go
rename to banyand/backup/restore_test.go
index 2e9cb3ef..830595af 100644
--- a/bydbbackup/pkg/restore_test.go
+++ b/banyand/backup/restore_test.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package pkg
+package backup
 
 import (
 	"context"
@@ -25,6 +25,7 @@ import (
 	"testing"
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/fs/remote/local"
 )
 
@@ -38,7 +39,7 @@ func TestRestoreDownload(t *testing.T) {
 	}
 
 	timeDir := "2023-10-10"
-	remoteFilePath := filepath.Join(timeDir, getCatalogName(commonv1.Catalog_CATALOG_STREAM), dataDir, "test.txt")
+	remoteFilePath := filepath.Join(timeDir, getCatalogName(commonv1.Catalog_CATALOG_STREAM), storage.DataDir, "test.txt")
 	content := "hello"
 	err = fs.Upload(context.Background(), remoteFilePath, strings.NewReader(content))
 	if err != nil {
@@ -50,7 +51,7 @@ func TestRestoreDownload(t *testing.T) {
 		t.Fatalf("restoreCatalog failed: %v", err)
 	}
 
-	localFilePath := filepath.Join(localRestoreDir, getCatalogName(commonv1.Catalog_CATALOG_STREAM), dataDir, "test.txt")
+	localFilePath := filepath.Join(localRestoreDir, getCatalogName(commonv1.Catalog_CATALOG_STREAM), storage.DataDir, "test.txt")
 	got, err := os.ReadFile(localFilePath)
 	if err != nil {
 		t.Fatalf("failed to read local file: %v", err)
@@ -69,8 +70,8 @@ func TestRestoreDelete(t *testing.T) {
 		t.Fatalf("failed to create remote FS: %v", err)
 	}
 
-	streamDir := filepath.Join(localRestoreDir, "stream", dataDir)
-	if err = os.MkdirAll(streamDir, dirPerm); err != nil {
+	streamDir := filepath.Join(localRestoreDir, "stream", storage.DataDir)
+	if err = os.MkdirAll(streamDir, storage.DirPerm); err != nil {
 		t.Fatalf("failed to create local stream directory: %v", err)
 	}
 	extraFilePath := filepath.Join(streamDir, "old.txt")
diff --git a/bydbbackup/pkg/timedir.go b/banyand/backup/timedir.go
similarity index 91%
rename from bydbbackup/pkg/timedir.go
rename to banyand/backup/timedir.go
index 12e6640c..7bac7d1c 100644
--- a/bydbbackup/pkg/timedir.go
+++ b/banyand/backup/timedir.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package pkg
+package backup
 
 import (
 	"context"
@@ -27,9 +27,9 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
-)
 
-const filePerm = 0o600
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
+)
 
 // NewTimeDirCommand creates a new time-dir command.
 func NewTimeDirCommand() *cobra.Command {
@@ -125,12 +125,15 @@ func newCreateCmd() *cobra.Command {
 					fmt.Fprintf(cmd.OutOrStdout(), "Skipping unknown catalog '%s': %v\n", cat, err)
 					continue
 				}
-				err = os.WriteFile(filePath, []byte(tValue), filePerm)
+				dirPath := filepath.Dir(filePath)
+				if err = os.MkdirAll(dirPath, storage.DirPerm); err != nil {
+					return fmt.Errorf("failed to create time-dir directory: %w", err)
+				}
+				err = os.WriteFile(filePath, []byte(tValue), storage.FilePerm)
 				if err != nil {
-					fmt.Fprintf(cmd.ErrOrStderr(), "Failed to create time-dir for catalog '%s' at %s: %v\n", cat, filePath, err)
-				} else {
-					fmt.Fprintf(cmd.OutOrStdout(), "Created time-dir for catalog '%s' at %s with content '%s'\n", cat, filePath, tValue)
+					return fmt.Errorf("failed to write time-dir file: %w", err)
 				}
+				fmt.Fprintf(cmd.OutOrStdout(), "Created time-dir for catalog '%s' at %s with content '%s'\n", cat, filePath, tValue)
 			}
 			return nil
 		},
@@ -228,11 +231,11 @@ func newDeleteCmd() *cobra.Command {
 func getLocalTimeDirFilePath(catalog, streamRoot, measureRoot, propertyRoot string) (string, error) {
 	switch strings.ToLower(catalog) {
 	case "stream":
-		return filepath.Join(streamRoot, fmt.Sprintf("%s-time-dir", "stream")), nil
+		return filepath.Join(streamRoot, "stream", "time-dir"), nil
 	case "measure":
-		return filepath.Join(measureRoot, fmt.Sprintf("%s-time-dir", "measure")), nil
+		return filepath.Join(measureRoot, "measure", "time-dir"), nil
 	case "property":
-		return filepath.Join(propertyRoot, fmt.Sprintf("%s-time-dir", "property")), nil
+		return filepath.Join(propertyRoot, "property", "time-dir"), nil
 	default:
 		return "", fmt.Errorf("unknown catalog type: %s", catalog)
 	}
diff --git a/bydbbackup/pkg/timedir_test.go b/banyand/backup/timedir_test.go
similarity index 76%
rename from bydbbackup/pkg/timedir_test.go
rename to banyand/backup/timedir_test.go
index 40bef667..e4fb4e38 100644
--- a/bydbbackup/pkg/timedir_test.go
+++ b/banyand/backup/timedir_test.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package pkg
+package backup
 
 import (
 	"bytes"
@@ -24,6 +24,8 @@ import (
 	"path/filepath"
 	"strings"
 	"testing"
+
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 )
 
 func TestNewCreateCmd(t *testing.T) {
@@ -31,23 +33,14 @@ func TestNewCreateCmd(t *testing.T) {
 	streamDir := filepath.Join(baseDir, "stream")
 	measureDir := filepath.Join(baseDir, "measure")
 	propertyDir := filepath.Join(baseDir, "property")
-	if err := os.MkdirAll(streamDir, dirPerm); err != nil {
-		t.Fatalf("Failed to create stream dir: %v", err)
-	}
-	if err := os.MkdirAll(measureDir, dirPerm); err != nil {
-		t.Fatalf("Failed to create measure dir: %v", err)
-	}
-	if err := os.MkdirAll(propertyDir, dirPerm); err != nil {
-		t.Fatalf("Failed to create property dir: %v", err)
-	}
 
 	content := "2023-10-12"
 	cmd := newCreateCmd()
 	cmd.SetArgs([]string{
 		content,
-		"--stream-root", streamDir,
-		"--measure-root", measureDir,
-		"--property-root", propertyDir,
+		"--stream-root", baseDir,
+		"--measure-root", baseDir,
+		"--property-root", baseDir,
 	})
 	if err := cmd.Execute(); err != nil {
 		t.Fatalf("newCreateCmd.Execute() error: %v", err)
@@ -61,7 +54,7 @@ func TestNewCreateCmd(t *testing.T) {
 		{"measure", measureDir},
 		{"property", propertyDir},
 	} {
-		fp := filepath.Join(dir.root, fmt.Sprintf("%s-time-dir", dir.name))
+		fp := filepath.Join(dir.root, "time-dir")
 		data, err := os.ReadFile(fp)
 		if err != nil {
 			t.Errorf("Catalog '%s': expected file at %s, error: %v", dir.name, fp, err)
@@ -79,12 +72,11 @@ func TestNewReadCmd(t *testing.T) {
 	measureDir := filepath.Join(baseDir, "measure")
 	propertyDir := filepath.Join(baseDir, "property")
 	for _, dir := range []string{streamDir, measureDir, propertyDir} {
-		if err := os.MkdirAll(dir, dirPerm); err != nil {
+		if err := os.MkdirAll(dir, storage.DirPerm); err != nil {
 			t.Fatalf("Failed to create dir %s: %v", dir, err)
 		}
-		catalog := filepath.Base(dir)
-		fp := filepath.Join(dir, fmt.Sprintf("%s-time-dir", catalog))
-		if err := os.WriteFile(fp, []byte("dummy-time"), filePerm); err != nil {
+		fp := filepath.Join(dir, "time-dir")
+		if err := os.WriteFile(fp, []byte("dummy-time"), storage.FilePerm); err != nil {
 			t.Fatalf("Failed to write file %s: %v", fp, err)
 		}
 	}
@@ -93,9 +85,9 @@ func TestNewReadCmd(t *testing.T) {
 	var outBuf bytes.Buffer
 	cmd.SetOut(&outBuf)
 	cmd.SetArgs([]string{
-		"--stream-root", streamDir,
-		"--measure-root", measureDir,
-		"--property-root", propertyDir,
+		"--stream-root", baseDir,
+		"--measure-root", baseDir,
+		"--property-root", baseDir,
 	})
 	if err := cmd.Execute(); err != nil {
 		t.Fatalf("newReadCmd.Execute() error: %v", err)
@@ -115,11 +107,10 @@ func TestNewDeleteCmd(t *testing.T) {
 	measureDir := filepath.Join(baseDir, "measure")
 	propertyDir := filepath.Join(baseDir, "property")
 	for _, dir := range []string{streamDir, measureDir, propertyDir} {
-		if err := os.MkdirAll(dir, dirPerm); err != nil {
+		if err := os.MkdirAll(dir, storage.DirPerm); err != nil {
 			t.Fatalf("Failed to create dir %s: %v", dir, err)
 		}
-		catalog := filepath.Base(dir)
-		fp := filepath.Join(dir, fmt.Sprintf("%s-time-dir", catalog))
+		fp := filepath.Join(dir, "time-dir")
 		if err := os.WriteFile(fp, []byte("to-be-deleted"), 0o600); err != nil {
 			t.Fatalf("Failed to write file %s: %v", fp, err)
 		}
@@ -127,9 +118,9 @@ func TestNewDeleteCmd(t *testing.T) {
 
 	cmd := newDeleteCmd()
 	cmd.SetArgs([]string{
-		"--stream-root", streamDir,
-		"--measure-root", measureDir,
-		"--property-root", propertyDir,
+		"--stream-root", baseDir,
+		"--measure-root", baseDir,
+		"--property-root", baseDir,
 	})
 	if err := cmd.Execute(); err != nil {
 		t.Fatalf("newDeleteCmd.Execute() error: %v", err)
diff --git a/bydbbackup/cmd/backup/main.go b/banyand/cmd/backup/main.go
similarity index 91%
rename from bydbbackup/cmd/backup/main.go
rename to banyand/cmd/backup/main.go
index e88a7996..916c19bc 100644
--- a/bydbbackup/cmd/backup/main.go
+++ b/banyand/cmd/backup/main.go
@@ -22,11 +22,11 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/apache/skywalking-banyandb/bydbbackup/pkg"
+	"github.com/apache/skywalking-banyandb/banyand/backup"
 )
 
 func main() {
-	cmd := pkg.NewBackupCommand()
+	cmd := backup.NewBackupCommand()
 	if err := cmd.Execute(); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
diff --git a/bydbbackup/cmd/restore/main.go b/banyand/cmd/restore/main.go
similarity index 91%
rename from bydbbackup/cmd/restore/main.go
rename to banyand/cmd/restore/main.go
index 333cc7d7..9f4339bb 100644
--- a/bydbbackup/cmd/restore/main.go
+++ b/banyand/cmd/restore/main.go
@@ -22,11 +22,11 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/apache/skywalking-banyandb/bydbbackup/pkg"
+	"github.com/apache/skywalking-banyandb/banyand/backup"
 )
 
 func main() {
-	cmd := pkg.NewRestoreCommand()
+	cmd := backup.NewRestoreCommand()
 	if err := cmd.Execute(); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
diff --git a/banyand/internal/storage/segment.go b/banyand/internal/storage/segment.go
index cb7047e6..8233dba6 100644
--- a/banyand/internal/storage/segment.go
+++ b/banyand/internal/storage/segment.go
@@ -376,10 +376,10 @@ func (sc *segmentController[T, O]) create(start time.Time) (*segment[T, O], erro
 		end = stdEnd
 	}
 	segPath := path.Join(sc.location, fmt.Sprintf(segTemplate, sc.format(start)))
-	lfs.MkdirPanicIfExist(segPath, dirPerm)
+	lfs.MkdirPanicIfExist(segPath, DirPerm)
 	data := []byte(currentVersion)
 	metadataPath := filepath.Join(segPath, metadataFilename)
-	lf, err := lfs.CreateLockFile(metadataPath, filePermission)
+	lf, err := lfs.CreateLockFile(metadataPath, FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", metadataPath, err)
 	}
diff --git a/banyand/internal/storage/shard.go b/banyand/internal/storage/shard.go
index 0c27f335..7133ed41 100644
--- a/banyand/internal/storage/shard.go
+++ b/banyand/internal/storage/shard.go
@@ -38,7 +38,7 @@ type shard[T TSTable] struct {
 
 func (s *segment[T, O]) openShard(ctx context.Context, id common.ShardID) (*shard[T], error) {
 	location := path.Join(s.location, fmt.Sprintf(shardTemplate, int(id)))
-	lfs.MkdirIfNotExist(location, dirPerm)
+	lfs.MkdirIfNotExist(location, DirPerm)
 	l := logger.Fetch(ctx, "shard"+strconv.Itoa(int(id)))
 	l.Info().Int("shard_id", int(id)).Str("path", location).Msg("creating a shard")
 	p := common.GetPosition(ctx)
diff --git a/banyand/internal/storage/snapshot.go b/banyand/internal/storage/snapshot.go
index 4cd3e28c..f8390637 100644
--- a/banyand/internal/storage/snapshot.go
+++ b/banyand/internal/storage/snapshot.go
@@ -29,7 +29,7 @@ func DeleteStaleSnapshots(root string, maxNum int, lfs fs.FileSystem) {
 	if maxNum <= 0 {
 		return
 	}
-	lfs.MkdirIfNotExist(root, dirPerm)
+	lfs.MkdirIfNotExist(root, DirPerm)
 	snapshots := lfs.ReadDir(root)
 	if len(snapshots) <= maxNum {
 		return
diff --git a/banyand/internal/storage/storage.go b/banyand/internal/storage/storage.go
index 469db5df..b0c2c269 100644
--- a/banyand/internal/storage/storage.go
+++ b/banyand/internal/storage/storage.go
@@ -49,7 +49,14 @@ const (
 	hourFormat = "2006010215"
 	dayFormat  = "20060102"
 
-	dirPerm = 0o700
+	// DirPerm is the permission of the directory.
+	DirPerm = 0o700
+	// SnapshotsDir is the directory for snapshots.
+	SnapshotsDir = "snapshots"
+	// DataDir is the directory for data.
+	DataDir = "data"
+	// FilePerm is the permission of the file.
+	FilePerm = 0o600
 )
 
 var (
diff --git a/banyand/internal/storage/tsdb.go b/banyand/internal/storage/tsdb.go
index 79579097..676ea38f 100644
--- a/banyand/internal/storage/tsdb.go
+++ b/banyand/internal/storage/tsdb.go
@@ -46,8 +46,7 @@ const (
 )
 
 const (
-	lockFilename   = "lock"
-	filePermission = 0o600
+	lockFilename = "lock"
 )
 
 // TSDBOpts wraps options to create a tsdb.
@@ -115,7 +114,7 @@ func OpenTSDB[T TSTable, O any](ctx context.Context, opts TSDBOpts[T, O]) (TSDB[
 	}
 	p := common.GetPosition(ctx)
 	location := filepath.Clean(opts.Location)
-	lfs.MkdirIfNotExist(location, dirPerm)
+	lfs.MkdirIfNotExist(location, DirPerm)
 	l := logger.Fetch(ctx, p.Database)
 	clock, _ := timestamp.GetClock(ctx)
 	scheduler := timestamp.NewScheduler(l, clock)
@@ -136,7 +135,7 @@ func OpenTSDB[T TSTable, O any](ctx context.Context, opts TSDBOpts[T, O]) (TSDB[
 	}
 	db.logger.Info().Str("path", opts.Location).Msg("initialized")
 	lockPath := filepath.Join(opts.Location, lockFilename)
-	lock, err := lfs.CreateLockFile(lockPath, filePermission)
+	lock, err := lfs.CreateLockFile(lockPath, FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", lockPath, err)
 	}
@@ -184,10 +183,10 @@ func (d *database[T, O]) TakeFileSnapshot(dst string) error {
 	for _, seg := range segments {
 		segDir := filepath.Base(seg.location)
 		segPath := filepath.Join(dst, segDir)
-		lfs.MkdirIfNotExist(segPath, dirPerm)
+		lfs.MkdirIfNotExist(segPath, DirPerm)
 
 		indexPath := filepath.Join(segPath, seriesIndexDirName)
-		lfs.MkdirIfNotExist(indexPath, dirPerm)
+		lfs.MkdirIfNotExist(indexPath, DirPerm)
 		if err := seg.index.store.TakeFileSnapshot(indexPath); err != nil {
 			return errors.Wrapf(err, "failed to snapshot index for segment %s", segDir)
 		}
@@ -199,7 +198,7 @@ func (d *database[T, O]) TakeFileSnapshot(dst string) error {
 		for _, shard := range *sLst {
 			shardDir := filepath.Base(shard.location)
 			shardPath := filepath.Join(segPath, shardDir)
-			lfs.MkdirIfNotExist(shardPath, dirPerm)
+			lfs.MkdirIfNotExist(shardPath, DirPerm)
 			if err := shard.table.TakeFileSnapshot(shardPath); err != nil {
 				return errors.Wrapf(err, "failed to snapshot shard %s in segment %s", shardDir, segDir)
 			}
diff --git a/banyand/measure/block_writer.go b/banyand/measure/block_writer.go
index 4a07291c..990abd0e 100644
--- a/banyand/measure/block_writer.go
+++ b/banyand/measure/block_writer.go
@@ -21,6 +21,7 @@ import (
 	"path/filepath"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/compress/zstd"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -175,15 +176,15 @@ func (bw *blockWriter) MustInitForMemPart(mp *memPart) {
 
 func (bw *blockWriter) mustInitForFilePart(fileSystem fs.FileSystem, path string) {
 	bw.reset()
-	fileSystem.MkdirPanicIfExist(path, dirPermission)
+	fileSystem.MkdirPanicIfExist(path, storage.DirPerm)
 	bw.writers.mustCreateTagFamilyWriters = func(name string) (fs.Writer, fs.Writer) {
-		return fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), filePermission),
-			fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesFilenameExt), filePermission)
+		return fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), storage.FilePerm),
+			fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesFilenameExt), storage.FilePerm)
 	}
-	bw.writers.metaWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, metaFilename), filePermission))
-	bw.writers.primaryWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, primaryFilename), filePermission))
-	bw.writers.timestampsWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, timestampsFilename), filePermission))
-	bw.writers.fieldValuesWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, fieldValuesFilename), filePermission))
+	bw.writers.metaWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, metaFilename), storage.FilePerm))
+	bw.writers.primaryWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, primaryFilename), storage.FilePerm))
+	bw.writers.timestampsWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, timestampsFilename), storage.FilePerm))
+	bw.writers.fieldValuesWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, fieldValuesFilename), storage.FilePerm))
 }
 
 func (bw *blockWriter) MustWriteDataPoints(sid common.SeriesID, timestamps, versions []int64, tagFamilies [][]nameValues, fields []nameValues) {
diff --git a/banyand/measure/part.go b/banyand/measure/part.go
index f4b6b812..da47baf9 100644
--- a/banyand/measure/part.go
+++ b/banyand/measure/part.go
@@ -25,6 +25,7 @@ import (
 	"sync/atomic"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/bytes"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -181,17 +182,17 @@ func (mp *memPart) mustInitFromDataPoints(dps *dataPoints) {
 }
 
 func (mp *memPart) mustFlush(fileSystem fs.FileSystem, path string) {
-	fileSystem.MkdirPanicIfExist(path, dirPermission)
+	fileSystem.MkdirPanicIfExist(path, storage.DirPerm)
 
-	fs.MustFlush(fileSystem, mp.meta.Buf, filepath.Join(path, metaFilename), filePermission)
-	fs.MustFlush(fileSystem, mp.primary.Buf, filepath.Join(path, primaryFilename), filePermission)
-	fs.MustFlush(fileSystem, mp.timestamps.Buf, filepath.Join(path, timestampsFilename), filePermission)
-	fs.MustFlush(fileSystem, mp.fieldValues.Buf, filepath.Join(path, fieldValuesFilename), filePermission)
+	fs.MustFlush(fileSystem, mp.meta.Buf, filepath.Join(path, metaFilename), storage.FilePerm)
+	fs.MustFlush(fileSystem, mp.primary.Buf, filepath.Join(path, primaryFilename), storage.FilePerm)
+	fs.MustFlush(fileSystem, mp.timestamps.Buf, filepath.Join(path, timestampsFilename), storage.FilePerm)
+	fs.MustFlush(fileSystem, mp.fieldValues.Buf, filepath.Join(path, fieldValuesFilename), storage.FilePerm)
 	for name, tf := range mp.tagFamilies {
-		fs.MustFlush(fileSystem, tf.Buf, filepath.Join(path, name+tagFamiliesFilenameExt), filePermission)
+		fs.MustFlush(fileSystem, tf.Buf, filepath.Join(path, name+tagFamiliesFilenameExt), storage.FilePerm)
 	}
 	for name, tfh := range mp.tagFamilyMetadata {
-		fs.MustFlush(fileSystem, tfh.Buf, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), filePermission)
+		fs.MustFlush(fileSystem, tfh.Buf, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), storage.FilePerm)
 	}
 
 	mp.partMetadata.mustWriteMetadata(fileSystem, path)
diff --git a/banyand/measure/part_metadata.go b/banyand/measure/part_metadata.go
index 7faaaf12..8d961d92 100644
--- a/banyand/measure/part_metadata.go
+++ b/banyand/measure/part_metadata.go
@@ -23,6 +23,7 @@ import (
 
 	"github.com/pkg/errors"
 
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
 )
@@ -86,7 +87,7 @@ func (pm *partMetadata) mustWriteMetadata(fileSystem fs.FileSystem, partPath str
 		return
 	}
 	metadataPath := filepath.Join(partPath, metadataFilename)
-	n, err := fileSystem.Write(metadata, metadataPath, filePermission)
+	n, err := fileSystem.Write(metadata, metadataPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot write metadata: %s", err)
 		return
diff --git a/banyand/measure/service.go b/banyand/measure/service.go
index 35f1aac2..c67101f8 100644
--- a/banyand/measure/service.go
+++ b/banyand/measure/service.go
@@ -27,6 +27,7 @@ import (
 	"github.com/apache/skywalking-banyandb/api/data"
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/banyand/metadata"
 	"github.com/apache/skywalking-banyandb/banyand/observability"
 	"github.com/apache/skywalking-banyandb/banyand/protector"
@@ -38,8 +39,6 @@ import (
 	resourceSchema "github.com/apache/skywalking-banyandb/pkg/schema"
 )
 
-const dataDir = "data"
-
 var (
 	errEmptyRootPath = errors.New("root path is empty")
 	// ErrMeasureNotExist denotes a measure doesn't exist in the metadata repo.
@@ -124,10 +123,10 @@ func (s *service) PreRun(ctx context.Context) error {
 	s.l = logger.GetLogger(s.Name())
 	s.lfs = fs.NewLocalFileSystemWithLogger(s.l)
 	path := path.Join(s.root, s.Name())
-	s.snapshotDir = filepath.Join(path, snapshotsDir)
+	s.snapshotDir = filepath.Join(path, storage.SnapshotsDir)
 	observability.UpdatePath(path)
 	s.localPipeline = queue.Local()
-	s.schemaRepo = newSchemaRepo(filepath.Join(path, dataDir), s)
+	s.schemaRepo = newSchemaRepo(filepath.Join(path, storage.DataDir), s)
 
 	if err := s.createNativeObservabilityGroup(ctx); err != nil {
 		return err
diff --git a/banyand/measure/snapshot.go b/banyand/measure/snapshot.go
index ad64e8eb..ddaf9e98 100644
--- a/banyand/measure/snapshot.go
+++ b/banyand/measure/snapshot.go
@@ -37,8 +37,6 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/schema"
 )
 
-const snapshotsDir = "snapshots"
-
 func (tst *tsTable) currentSnapshot() *snapshot {
 	tst.RLock()
 	defer tst.RUnlock()
@@ -186,7 +184,7 @@ func (tst *tsTable) createMetadata(dst string, snapshot *snapshot) {
 		logger.Panicf("cannot marshal partNames to JSON: %s", err)
 	}
 	snapshotPath := filepath.Join(dst, snapshotName(snapshot.epoch))
-	lf, err := tst.fileSystem.CreateFile(snapshotPath, filePermission)
+	lf, err := tst.fileSystem.CreateFile(snapshotPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", snapshotPath, err)
 	}
@@ -254,7 +252,7 @@ func (s *snapshotListener) Rev(ctx context.Context, message bus.Message) bus.Mes
 			return bus.NewMessage(bus.MessageID(time.Now().UnixNano()), nil)
 		default:
 		}
-		if errGroup := s.s.takeGroupSnapshot(filepath.Join(s.s.snapshotDir, sn, dataDir), g.GetSchema().Metadata.Name); err != nil {
+		if errGroup := s.s.takeGroupSnapshot(filepath.Join(s.s.snapshotDir, sn, storage.DataDir), g.GetSchema().Metadata.Name); err != nil {
 			s.s.l.Error().Err(errGroup).Str("group", g.GetSchema().Metadata.Name).Msg("fail to take group snapshot")
 			err = multierr.Append(err, errGroup)
 			continue
diff --git a/banyand/measure/tstable.go b/banyand/measure/tstable.go
index 28d9c9e2..1684af26 100644
--- a/banyand/measure/tstable.go
+++ b/banyand/measure/tstable.go
@@ -31,6 +31,7 @@ import (
 	"time"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
 	"github.com/apache/skywalking-banyandb/pkg/pool"
@@ -41,8 +42,6 @@ import (
 
 const (
 	snapshotSuffix = ".snp"
-	filePermission = 0o600
-	dirPermission  = 0o700
 )
 
 func newTSTable(fileSystem fs.FileSystem, rootPath string, p common.Position,
@@ -201,7 +200,7 @@ func (tst *tsTable) mustWriteSnapshot(snapshot uint64, partNames []string) {
 		logger.Panicf("cannot marshal partNames to JSON: %s", err)
 	}
 	snapshotPath := filepath.Join(tst.root, snapshotName(snapshot))
-	lf, err := tst.fileSystem.CreateLockFile(snapshotPath, filePermission)
+	lf, err := tst.fileSystem.CreateLockFile(snapshotPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", snapshotPath, err)
 	}
diff --git a/banyand/property/db.go b/banyand/property/db.go
index 37d4f53b..8e98da85 100644
--- a/banyand/property/db.go
+++ b/banyand/property/db.go
@@ -30,6 +30,7 @@ import (
 
 	"github.com/apache/skywalking-banyandb/api/common"
 	propertyv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/property/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/banyand/observability"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/index/inverted"
@@ -37,9 +38,7 @@ import (
 )
 
 const (
-	dirPerm        = 0o700
-	filePermission = 0o600
-	lockFilename   = "lock"
+	lockFilename = "lock"
 )
 
 var (
@@ -59,7 +58,7 @@ type database struct {
 
 func openDB(ctx context.Context, location string, flushInterval time.Duration, omr observability.MetricsRegistry) (*database, error) {
 	loc := filepath.Clean(location)
-	lfs.MkdirIfNotExist(loc, dirPerm)
+	lfs.MkdirIfNotExist(loc, storage.DirPerm)
 	l := logger.GetLogger("property")
 
 	db := &database{
@@ -73,7 +72,7 @@ func openDB(ctx context.Context, location string, flushInterval time.Duration, o
 	}
 	db.logger.Info().Str("path", loc).Msg("initialized")
 	lockPath := filepath.Join(loc, lockFilename)
-	lock, err := lfs.CreateLockFile(lockPath, filePermission)
+	lock, err := lfs.CreateLockFile(lockPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", lockPath, err)
 	}
diff --git a/banyand/property/listener.go b/banyand/property/listener.go
index a7025314..f02b7ac2 100644
--- a/banyand/property/listener.go
+++ b/banyand/property/listener.go
@@ -40,8 +40,6 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/query"
 )
 
-const snapshotsDir = "snapshots"
-
 var (
 	_ bus.MessageListener = (*updateListener)(nil)
 	_ bus.MessageListener = (*deleteListener)(nil)
@@ -243,8 +241,8 @@ func (s *snapshotListener) Rev(ctx context.Context, message bus.Message) bus.Mes
 			return bus.NewMessage(bus.MessageID(time.Now().UnixNano()), nil)
 		default:
 		}
-		snpDir := path.Join(s.s.snapshotDir, sn, dataDir, filepath.Base(shard.location))
-		lfs.MkdirPanicIfExist(snpDir, dirPerm)
+		snpDir := path.Join(s.s.snapshotDir, sn, storage.DataDir, filepath.Base(shard.location))
+		lfs.MkdirPanicIfExist(snpDir, storage.DirPerm)
 		err := shard.store.TakeFileSnapshot(snpDir)
 		if err != nil {
 			s.s.l.Error().Err(err).Str("shard", filepath.Base(shard.location)).Msg("fail to take shard snapshot")
diff --git a/banyand/property/service.go b/banyand/property/service.go
index 4932cbae..99465419 100644
--- a/banyand/property/service.go
+++ b/banyand/property/service.go
@@ -29,6 +29,7 @@ import (
 	"github.com/apache/skywalking-banyandb/api/common"
 	"github.com/apache/skywalking-banyandb/api/data"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/banyand/metadata"
 	"github.com/apache/skywalking-banyandb/banyand/observability"
 	"github.com/apache/skywalking-banyandb/banyand/queue"
@@ -39,7 +40,6 @@ import (
 
 const (
 	defaultFlushTimeout = 5 * time.Second
-	dataDir             = "data"
 )
 
 var (
@@ -97,7 +97,7 @@ func (s *service) PreRun(ctx context.Context) error {
 	s.l = logger.GetLogger(s.Name())
 	s.lfs = fs.NewLocalFileSystemWithLogger(s.l)
 	path := path.Join(s.root, s.Name())
-	s.snapshotDir = filepath.Join(path, snapshotsDir)
+	s.snapshotDir = filepath.Join(path, storage.SnapshotsDir)
 	observability.UpdatePath(path)
 	val := ctx.Value(common.ContextNodeKey)
 	if val == nil {
@@ -107,7 +107,7 @@ func (s *service) PreRun(ctx context.Context) error {
 	s.nodeID = node.NodeID
 
 	var err error
-	s.db, err = openDB(ctx, filepath.Join(path, dataDir), s.flushTimeout, s.omr)
+	s.db, err = openDB(ctx, filepath.Join(path, storage.DataDir), s.flushTimeout, s.omr)
 	if err != nil {
 		return err
 	}
diff --git a/banyand/stream/block_writer.go b/banyand/stream/block_writer.go
index f55f9ebf..bd40b67b 100644
--- a/banyand/stream/block_writer.go
+++ b/banyand/stream/block_writer.go
@@ -21,6 +21,7 @@ import (
 	"path/filepath"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/compress/zstd"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -170,14 +171,14 @@ func (bw *blockWriter) MustInitForMemPart(mp *memPart) {
 
 func (bw *blockWriter) mustInitForFilePart(fileSystem fs.FileSystem, path string) {
 	bw.reset()
-	fileSystem.MkdirPanicIfExist(path, dirPermission)
+	fileSystem.MkdirPanicIfExist(path, storage.DirPerm)
 	bw.writers.mustCreateTagFamilyWriters = func(name string) (fs.Writer, fs.Writer) {
-		return fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), filePermission),
-			fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesFilenameExt), filePermission)
+		return fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), storage.FilePerm),
+			fs.MustCreateFile(fileSystem, filepath.Join(path, name+tagFamiliesFilenameExt), storage.FilePerm)
 	}
-	bw.writers.metaWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, metaFilename), filePermission))
-	bw.writers.primaryWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, primaryFilename), filePermission))
-	bw.writers.timestampsWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, timestampsFilename), filePermission))
+	bw.writers.metaWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, metaFilename), storage.FilePerm))
+	bw.writers.primaryWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, primaryFilename), storage.FilePerm))
+	bw.writers.timestampsWriter.init(fs.MustCreateFile(fileSystem, filepath.Join(path, timestampsFilename), storage.FilePerm))
 }
 
 func (bw *blockWriter) MustWriteElements(sid common.SeriesID, timestamps []int64, elementIDs []uint64, tagFamilies [][]tagValues) {
diff --git a/banyand/stream/part.go b/banyand/stream/part.go
index d0dce1f9..69e36b74 100644
--- a/banyand/stream/part.go
+++ b/banyand/stream/part.go
@@ -25,6 +25,7 @@ import (
 	"sync/atomic"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/bytes"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -164,16 +165,16 @@ func (mp *memPart) mustInitFromElements(es *elements) {
 }
 
 func (mp *memPart) mustFlush(fileSystem fs.FileSystem, path string) {
-	fileSystem.MkdirPanicIfExist(path, dirPermission)
+	fileSystem.MkdirPanicIfExist(path, storage.DirPerm)
 
-	fs.MustFlush(fileSystem, mp.meta.Buf, filepath.Join(path, metaFilename), filePermission)
-	fs.MustFlush(fileSystem, mp.primary.Buf, filepath.Join(path, primaryFilename), filePermission)
-	fs.MustFlush(fileSystem, mp.timestamps.Buf, filepath.Join(path, timestampsFilename), filePermission)
+	fs.MustFlush(fileSystem, mp.meta.Buf, filepath.Join(path, metaFilename), storage.FilePerm)
+	fs.MustFlush(fileSystem, mp.primary.Buf, filepath.Join(path, primaryFilename), storage.FilePerm)
+	fs.MustFlush(fileSystem, mp.timestamps.Buf, filepath.Join(path, timestampsFilename), storage.FilePerm)
 	for name, tf := range mp.tagFamilies {
-		fs.MustFlush(fileSystem, tf.Buf, filepath.Join(path, name+tagFamiliesFilenameExt), filePermission)
+		fs.MustFlush(fileSystem, tf.Buf, filepath.Join(path, name+tagFamiliesFilenameExt), storage.FilePerm)
 	}
 	for name, tfh := range mp.tagFamilyMetadata {
-		fs.MustFlush(fileSystem, tfh.Buf, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), filePermission)
+		fs.MustFlush(fileSystem, tfh.Buf, filepath.Join(path, name+tagFamiliesMetadataFilenameExt), storage.FilePerm)
 	}
 
 	mp.partMetadata.mustWriteMetadata(fileSystem, path)
diff --git a/banyand/stream/part_metadata.go b/banyand/stream/part_metadata.go
index 075d2d00..cb0dd576 100644
--- a/banyand/stream/part_metadata.go
+++ b/banyand/stream/part_metadata.go
@@ -23,6 +23,7 @@ import (
 
 	"github.com/pkg/errors"
 
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
 )
@@ -86,7 +87,7 @@ func (pm *partMetadata) mustWriteMetadata(fileSystem fs.FileSystem, partPath str
 		return
 	}
 	metadataPath := filepath.Join(partPath, metadataFilename)
-	n, err := fileSystem.Write(metadata, metadataPath, filePermission)
+	n, err := fileSystem.Write(metadata, metadataPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot write metadata: %s", err)
 		return
diff --git a/banyand/stream/service.go b/banyand/stream/service.go
index e1e50e70..0c4fd4cd 100644
--- a/banyand/stream/service.go
+++ b/banyand/stream/service.go
@@ -27,6 +27,7 @@ import (
 	"github.com/apache/skywalking-banyandb/api/data"
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/banyand/metadata"
 	"github.com/apache/skywalking-banyandb/banyand/observability"
 	"github.com/apache/skywalking-banyandb/banyand/protector"
@@ -38,8 +39,6 @@ import (
 	resourceSchema "github.com/apache/skywalking-banyandb/pkg/schema"
 )
 
-const dataDir = "data"
-
 var (
 	errEmptyRootPath = errors.New("root path is empty")
 	// ErrStreamNotExist denotes a stream doesn't exist in the metadata repo.
@@ -124,10 +123,10 @@ func (s *service) PreRun(_ context.Context) error {
 	s.l = logger.GetLogger(s.Name())
 	s.lfs = fs.NewLocalFileSystemWithLogger(s.l)
 	path := path.Join(s.root, s.Name())
-	s.snapshotDir = filepath.Join(path, snapshotsDir)
+	s.snapshotDir = filepath.Join(path, storage.SnapshotsDir)
 	observability.UpdatePath(path)
 	s.localPipeline = queue.Local()
-	s.schemaRepo = newSchemaRepo(filepath.Join(path, dataDir), s)
+	s.schemaRepo = newSchemaRepo(filepath.Join(path, storage.DataDir), s)
 	// run a serial watcher
 
 	if err := s.pipeline.Subscribe(data.TopicSnapshot, &snapshotListener{s: s}); err != nil {
diff --git a/banyand/stream/snapshot.go b/banyand/stream/snapshot.go
index df00698e..1a44c4f5 100644
--- a/banyand/stream/snapshot.go
+++ b/banyand/stream/snapshot.go
@@ -37,8 +37,6 @@ import (
 	"github.com/apache/skywalking-banyandb/pkg/schema"
 )
 
-const snapshotsDir = "snapshots"
-
 func (tst *tsTable) currentSnapshot() *snapshot {
 	tst.RLock()
 	defer tst.RUnlock()
@@ -152,7 +150,7 @@ func parseSnapshot(name string) (uint64, error) {
 
 func (tst *tsTable) TakeFileSnapshot(dst string) error {
 	indexDir := filepath.Join(dst, filepath.Base(tst.index.location))
-	tst.fileSystem.MkdirPanicIfExist(indexDir, dirPermission)
+	tst.fileSystem.MkdirPanicIfExist(indexDir, storage.DirPerm)
 	if err := tst.index.store.TakeFileSnapshot(indexDir); err != nil {
 		return fmt.Errorf("failed to take file snapshot for index: %w", err)
 	}
@@ -192,7 +190,7 @@ func (tst *tsTable) createMetadata(dst string, snapshot *snapshot) {
 		logger.Panicf("cannot marshal partNames to JSON: %s", err)
 	}
 	snapshotPath := filepath.Join(dst, snapshotName(snapshot.epoch))
-	lf, err := tst.fileSystem.CreateFile(snapshotPath, filePermission)
+	lf, err := tst.fileSystem.CreateFile(snapshotPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", snapshotPath, err)
 	}
@@ -260,7 +258,7 @@ func (s *snapshotListener) Rev(ctx context.Context, message bus.Message) bus.Mes
 			return bus.NewMessage(bus.MessageID(time.Now().UnixNano()), nil)
 		default:
 		}
-		if errGroup := s.s.takeGroupSnapshot(filepath.Join(s.s.snapshotDir, sn, dataDir), g.GetSchema().Metadata.Name); err != nil {
+		if errGroup := s.s.takeGroupSnapshot(filepath.Join(s.s.snapshotDir, sn, storage.DataDir), g.GetSchema().Metadata.Name); err != nil {
 			s.s.l.Error().Err(errGroup).Str("group", g.GetSchema().Metadata.Name).Msg("fail to take group snapshot")
 			err = multierr.Append(err, errGroup)
 			continue
diff --git a/banyand/stream/tstable.go b/banyand/stream/tstable.go
index 14997423..6a1285a4 100644
--- a/banyand/stream/tstable.go
+++ b/banyand/stream/tstable.go
@@ -32,6 +32,7 @@ import (
 	"time"
 
 	"github.com/apache/skywalking-banyandb/api/common"
+	"github.com/apache/skywalking-banyandb/banyand/internal/storage"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/index/inverted"
 	"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -43,8 +44,6 @@ import (
 
 const (
 	snapshotSuffix = ".snp"
-	filePermission = 0o600
-	dirPermission  = 0o700
 )
 
 type tsTable struct {
@@ -133,7 +132,7 @@ func (tst *tsTable) mustWriteSnapshot(snapshot uint64, partNames []string) {
 		logger.Panicf("cannot marshal partNames to JSON: %s", err)
 	}
 	snapshotPath := filepath.Join(tst.root, snapshotName(snapshot))
-	lf, err := tst.fileSystem.CreateLockFile(snapshotPath, filePermission)
+	lf, err := tst.fileSystem.CreateLockFile(snapshotPath, storage.FilePerm)
 	if err != nil {
 		logger.Panicf("cannot create lock file %s: %s", snapshotPath, err)
 	}
diff --git a/bydbbackup/Makefile b/bydbbackup/Makefile
deleted file mode 100644
index 4bcdf289..00000000
--- a/bydbbackup/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-# Licensed to Apache Software Foundation (ASF) under one or more contributor
-# license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright
-# ownership. Apache Software Foundation (ASF) licenses this file to you under
-# the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-NAME := bydbbackup
-BINARIES := $(NAME)-backup $(NAME)-restore
-
-IMG_NAME := skywalking-bydbbackup
-
-include ../scripts/build/version.mk
-include ../scripts/build/base.mk
-include ../scripts/build/generate_go.mk
-include ../scripts/build/build.mk
-include ../scripts/build/docker.mk
-include ../scripts/build/test.mk
-include ../scripts/build/lint.mk
-include ../scripts/build/vendor.mk
-include ../scripts/build/help.mk
-
-prepare-build: generate
diff --git a/dist/LICENSE b/dist/LICENSE
index df6478e5..5a520df6 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -185,17 +185,17 @@ Apache-2.0 licenses
     github.com/blevesearch/vellum v1.1.0 Apache-2.0
     github.com/coreos/go-semver v0.3.1 Apache-2.0
     github.com/coreos/go-systemd/v22 v22.5.0 Apache-2.0
-    github.com/envoyproxy/protoc-gen-validate v1.1.0 Apache-2.0
+    github.com/envoyproxy/protoc-gen-validate v1.2.1 Apache-2.0
     github.com/go-logr/logr v1.4.2 Apache-2.0
     github.com/go-logr/stdr v1.2.2 Apache-2.0
     github.com/google/btree v1.1.3 Apache-2.0
-    github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad Apache-2.0
+    github.com/google/pprof v0.0.0-20250208200701-d0013a598941 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 Apache-2.0
     github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 Apache-2.0
     github.com/inconshreveable/mousetrap v1.1.0 Apache-2.0
-    github.com/jonboulle/clockwork v0.4.0 Apache-2.0
+    github.com/jonboulle/clockwork v0.5.0 Apache-2.0
     github.com/kkdai/maglev v0.2.0 Apache-2.0
     github.com/machinebox/graphql v0.2.2 Apache-2.0
     github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd Apache-2.0
@@ -204,37 +204,37 @@ Apache-2.0 licenses
     github.com/oklog/run v1.1.0 Apache-2.0
     github.com/prometheus/client_golang v1.20.5 Apache-2.0
     github.com/prometheus/client_model v0.6.1 Apache-2.0
-    github.com/prometheus/common v0.61.0 Apache-2.0
+    github.com/prometheus/common v0.62.0 Apache-2.0
     github.com/prometheus/procfs v0.15.1 Apache-2.0
     github.com/soheilhy/cmux v0.1.5 Apache-2.0
-    github.com/spf13/afero v1.11.0 Apache-2.0
+    github.com/spf13/afero v1.12.0 Apache-2.0
     github.com/spf13/cobra v1.8.1 Apache-2.0
     github.com/tklauser/numcpus v0.9.0 Apache-2.0
     github.com/zinclabs/bluge_segment_api v1.0.0 Apache-2.0
-    go.etcd.io/etcd/api/v3 v3.5.17 Apache-2.0
-    go.etcd.io/etcd/client/pkg/v3 v3.5.17 Apache-2.0
-    go.etcd.io/etcd/client/v2 v2.305.17 Apache-2.0
-    go.etcd.io/etcd/client/v3 v3.5.17 Apache-2.0
-    go.etcd.io/etcd/pkg/v3 v3.5.17 Apache-2.0
-    go.etcd.io/etcd/raft/v3 v3.5.17 Apache-2.0
-    go.etcd.io/etcd/server/v3 v3.5.17 Apache-2.0
+    go.etcd.io/etcd/api/v3 v3.5.18 Apache-2.0
+    go.etcd.io/etcd/client/pkg/v3 v3.5.18 Apache-2.0
+    go.etcd.io/etcd/client/v2 v2.305.18 Apache-2.0
+    go.etcd.io/etcd/client/v3 v3.5.18 Apache-2.0
+    go.etcd.io/etcd/pkg/v3 v3.5.18 Apache-2.0
+    go.etcd.io/etcd/raft/v3 v3.5.18 Apache-2.0
+    go.etcd.io/etcd/server/v3 v3.5.18 Apache-2.0
     go.opentelemetry.io/auto/sdk v1.1.0 Apache-2.0
-    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 Apache-2.0
-    go.opentelemetry.io/otel v1.33.0 Apache-2.0
-    go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 Apache-2.0
-    go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 Apache-2.0
-    go.opentelemetry.io/otel/metric v1.33.0 Apache-2.0
-    go.opentelemetry.io/otel/sdk v1.33.0 Apache-2.0
-    go.opentelemetry.io/otel/trace v1.33.0 Apache-2.0
-    go.opentelemetry.io/proto/otlp v1.4.0 Apache-2.0
+    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 Apache-2.0
+    go.opentelemetry.io/otel v1.34.0 Apache-2.0
+    go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 Apache-2.0
+    go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 Apache-2.0
+    go.opentelemetry.io/otel/metric v1.34.0 Apache-2.0
+    go.opentelemetry.io/otel/sdk v1.34.0 Apache-2.0
+    go.opentelemetry.io/otel/trace v1.34.0 Apache-2.0
+    go.opentelemetry.io/proto/otlp v1.5.0 Apache-2.0
     go.uber.org/mock v0.5.0 Apache-2.0
-    google.golang.org/genproto v0.0.0-20241219192143-6b3ec007d9bb Apache-2.0
-    google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb Apache-2.0
-    google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb Apache-2.0
-    google.golang.org/grpc v1.69.2 Apache-2.0
+    google.golang.org/genproto v0.0.0-20250212204824-5a70512c5d8b Apache-2.0
+    google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b Apache-2.0
+    google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b Apache-2.0
+    google.golang.org/grpc v1.70.0 Apache-2.0
     gopkg.in/ini.v1 v1.67.0 Apache-2.0
     gopkg.in/yaml.v2 v2.4.0 Apache-2.0
-    skywalking.apache.org/repo/goapi v0.0.0-20241129131257-944118bb91b8 Apache-2.0
+    skywalking.apache.org/repo/goapi v0.0.0-20241231024338-a68ffc997f46 Apache-2.0
 
 ========================================================================
 Apache-2.0 and BSD-3-Clause licenses
@@ -272,24 +272,24 @@ BSD-3-Clause licenses
     github.com/google/go-cmp v0.6.0 BSD-3-Clause
     github.com/google/uuid v1.6.0 BSD-3-Clause
     github.com/grpc-ecosystem/grpc-gateway v1.16.0 BSD-3-Clause
-    github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 BSD-3-Clause
+    github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 BSD-3-Clause
     github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 BSD-3-Clause
     github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 BSD-3-Clause
     github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 BSD-3-Clause
     github.com/sagikazarmark/slog-shim v0.1.0 BSD-3-Clause
     github.com/shirou/gopsutil/v3 v3.24.5 BSD-3-Clause
-    github.com/spf13/pflag v1.0.5 BSD-3-Clause
+    github.com/spf13/pflag v1.0.6 BSD-3-Clause
     github.com/tklauser/go-sysconf v0.3.14 BSD-3-Clause
     github.com/xhit/go-str2duration/v2 v2.1.0 BSD-3-Clause
-    golang.org/x/crypto v0.31.0 BSD-3-Clause
-    golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 BSD-3-Clause
-    golang.org/x/mod v0.22.0 BSD-3-Clause
-    golang.org/x/net v0.33.0 BSD-3-Clause
-    golang.org/x/sys v0.28.0 BSD-3-Clause
-    golang.org/x/text v0.21.0 BSD-3-Clause
-    golang.org/x/time v0.8.0 BSD-3-Clause
-    golang.org/x/tools v0.28.0 BSD-3-Clause
-    google.golang.org/protobuf v1.36.0 BSD-3-Clause
+    golang.org/x/crypto v0.33.0 BSD-3-Clause
+    golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac BSD-3-Clause
+    golang.org/x/mod v0.23.0 BSD-3-Clause
+    golang.org/x/net v0.35.0 BSD-3-Clause
+    golang.org/x/sys v0.30.0 BSD-3-Clause
+    golang.org/x/text v0.22.0 BSD-3-Clause
+    golang.org/x/time v0.10.0 BSD-3-Clause
+    golang.org/x/tools v0.30.0 BSD-3-Clause
+    google.golang.org/protobuf v1.36.5 BSD-3-Clause
 
 ========================================================================
 BSD-3-Clause and Apache-2.0 and MIT licenses
@@ -315,32 +315,32 @@ MIT licenses
 
     github.com/SkyAPM/clock v1.3.1-0.20220809233656-dc7607c94a97 MIT
     github.com/VictoriaMetrics/fastcache v1.12.2 MIT
-    github.com/axiomhq/hyperloglog v0.2.2 MIT
+    github.com/axiomhq/hyperloglog v0.2.3 MIT
     github.com/beorn7/perks v1.0.1 MIT
     github.com/blevesearch/go-porterstemmer v1.0.3 MIT
     github.com/caio/go-tdigest v3.1.0+incompatible MIT
     github.com/cenkalti/backoff/v4 v4.3.0 MIT
     github.com/cespare/xxhash/v2 v2.3.0 MIT
     github.com/cpuguy83/go-md2man/v2 v2.0.6 MIT
-    github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 MIT
+    github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 MIT
     github.com/dustin/go-humanize v1.0.1 MIT
-    github.com/go-chi/chi/v5 v5.2.0 MIT
+    github.com/go-chi/chi/v5 v5.2.1 MIT
     github.com/go-ole/go-ole v1.3.0 MIT
-    github.com/go-resty/resty/v2 v2.16.2 MIT
+    github.com/go-resty/resty/v2 v2.16.5 MIT
     github.com/go-task/slim-sprig/v3 v3.0.0 MIT
     github.com/golang-jwt/jwt/v4 v4.5.1 MIT
     github.com/json-iterator/go v1.1.12 MIT
-    github.com/mattn/go-colorable v0.1.13 MIT
+    github.com/mattn/go-colorable v0.1.14 MIT
     github.com/mattn/go-isatty v0.0.20 MIT
     github.com/mitchellh/mapstructure v1.5.0 MIT
     github.com/montanaflynn/stats v0.7.1 MIT
-    github.com/onsi/ginkgo/v2 v2.22.1 MIT
-    github.com/onsi/gomega v1.36.1 MIT
+    github.com/onsi/ginkgo/v2 v2.22.2 MIT
+    github.com/onsi/gomega v1.36.2 MIT
     github.com/pelletier/go-toml/v2 v2.2.3 MIT
     github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 MIT
     github.com/robfig/cron/v3 v3.0.1 MIT
     github.com/rs/zerolog v1.33.0 MIT
-    github.com/sagikazarmark/locafero v0.6.0 MIT
+    github.com/sagikazarmark/locafero v0.7.0 MIT
     github.com/sirupsen/logrus v1.9.3 MIT
     github.com/sourcegraph/conc v0.3.0 MIT
     github.com/spf13/cast v1.7.1 MIT
@@ -353,7 +353,7 @@ MIT licenses
     github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 MIT
     github.com/yusufpapurcu/wmi v1.2.4 MIT
     github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 MIT
-    go.etcd.io/bbolt v1.3.11 MIT
+    go.etcd.io/bbolt v1.4.0 MIT
     go.uber.org/automaxprocs v1.6.0 MIT
     go.uber.org/multierr v1.11.0 MIT
     go.uber.org/zap v1.27.0 MIT
@@ -398,7 +398,7 @@ Apache-2.0 licenses
 ========================================================================
 
     detect-libc 1.0.3 Apache-2.0
-    echarts 5.5.1 Apache-2.0
+    echarts 5.6.0 Apache-2.0
 
 ========================================================================
 BSD-2-Clause licenses
@@ -412,7 +412,7 @@ BSD-3-Clause licenses
 
     normalize-wheel-es 1.2.0 BSD-3-Clause
     source-map-js 1.2.1 BSD-3-Clause
-    zrender 5.6.0 BSD-3-Clause
+    zrender 5.6.1 BSD-3-Clause
 
 ========================================================================
 ISC licenses
@@ -420,8 +420,8 @@ ISC licenses
 
     graceful-fs 4.2.11 ISC
     picocolors 1.1.1 ISC
-    semver 7.6.3 ISC
-    yaml 2.6.1 ISC
+    semver 7.7.1 ISC
+    yaml 2.7.0 ISC
 
 ========================================================================
 MIT licenses
@@ -429,19 +429,19 @@ MIT licenses
 
     @babel/helper-string-parser 7.25.9 MIT
     @babel/helper-validator-identifier 7.25.9 MIT
-    @babel/parser 7.26.3 MIT
-    @babel/types 7.26.3 MIT
+    @babel/parser 7.26.8 MIT
+    @babel/types 7.26.8 MIT
     @ctrl/tinycolor 3.6.1 MIT
     @element-plus/icons-vue 2.3.1 MIT
-    @floating-ui/core 1.6.8 MIT
-    @floating-ui/dom 1.6.12 MIT
-    @floating-ui/utils 0.2.8 MIT
+    @floating-ui/core 1.6.9 MIT
+    @floating-ui/dom 1.6.13 MIT
+    @floating-ui/utils 0.2.9 MIT
     @jridgewell/sourcemap-codec 1.5.0 MIT
-    @parcel/watcher 2.5.0 MIT
-    @parcel/watcher-linux-x64-glibc 2.5.0 MIT
-    @parcel/watcher-linux-x64-musl 2.5.0 MIT
+    @parcel/watcher 2.5.1 MIT
+    @parcel/watcher-linux-x64-glibc 2.5.1 MIT
+    @parcel/watcher-linux-x64-musl 2.5.1 MIT
     @popperjs/core 2.11.7 MIT
-    @types/lodash 4.17.13 MIT
+    @types/lodash 4.17.15 MIT
     @types/lodash-es 4.17.12 MIT
     @types/web-bluetooth 0.0.16 MIT
     @vue/compiler-core 3.5.13 MIT
@@ -467,7 +467,7 @@ MIT licenses
     csstype 3.1.3 MIT
     dayjs 1.11.13 MIT
     delayed-stream 1.0.0 MIT
-    element-plus 2.9.1 MIT
+    element-plus 2.9.4 MIT
     escape-html 1.0.3 MIT
     estree-walker 2.0.2 MIT
     fill-range 7.1.1 MIT
@@ -491,11 +491,11 @@ MIT licenses
     nanoid 3.3.8 MIT
     node-addon-api 7.1.1 MIT
     picomatch 2.3.1 MIT
-    pinia 2.3.0 MIT
-    postcss 8.4.49 MIT
+    pinia 2.3.1 MIT
+    postcss 8.5.2 MIT
     proxy-from-env 1.1.0 MIT
-    readdirp 4.0.2 MIT
-    sass 1.83.0 MIT
+    readdirp 4.1.1 MIT
+    sass 1.84.0 MIT
     to-regex-range 5.0.1 MIT
     universalify 2.0.1 MIT
     vue 3.5.13 MIT
diff --git a/dist/licenses/ui-licenses/license-sass.txt b/dist/licenses/ui-licenses/license-sass.txt
index d280a1a1..e37a9d84 100644
--- a/dist/licenses/ui-licenses/license-sass.txt
+++ b/dist/licenses/ui-licenses/license-sass.txt
@@ -615,8 +615,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 --------------------------------------------------------------------------------
 
-coverage, dart_style, dartdoc, glob, http, http_parser, matcher, path, pool,
-pub_semver, source_span, string_scanner, test and watcher license:
+coverage, dartdoc, glob, http, http_parser, matcher, path, pool, pub_semver,
+source_span, string_scanner, test and watcher license:
 
 Copyright 2014, the Dart project authors. 
 
@@ -1183,11 +1183,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 --------------------------------------------------------------------------------
 
-petitparser and xml license:
+petitparser license:
 
 The MIT License
 
-Copyright (c) 2006-2023 Lukas Renggli.
+Copyright (c) 2006-2025 Lukas Renggli.
 All rights reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1640,6 +1640,34 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
+--------------------------------------------------------------------------------
+
+xml license:
+
+The MIT License
+
+Copyright (c) 2006-2023 Lukas Renggli.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
 --------------------------------------------------------------------------------
 
 yaml license:
diff --git a/docs/operation/backup.md b/docs/operation/backup.md
index b2dd043c..617add77 100644
--- a/docs/operation/backup.md
+++ b/docs/operation/backup.md
@@ -39,7 +39,7 @@ To perform a one-time backup, run the backup command with the required flags. At
 
 ### Scheduled Backup
 
-To enable periodic backups, provide the `--schedule` flag with a schedule style (e.g., `hourly` or `daily`) and set your preferred time style using `--time-style`. The supported schedule expressions based on the tool’s internal map are:
+To enable periodic backups, provide the `--schedule` flag with a schedule style (e.g., @yearly, @monthly, @weekly, @daily, @hourly or @every <duration>) and set your preferred time style using `--time-style`. The supported schedule expressions based on the tool’s internal map are:
 
 - **Hourly:** Schedules at "5 * * * *" (runs on the 5th minute of every hour).
 - **Daily:** Schedules at "5 0 * * *" (runs at 00:05 every day).
@@ -47,7 +47,7 @@ To enable periodic backups, provide the `--schedule` flag with a schedule style
 **Example Command:**
 
 ```bash
-./backup --dest "file:///backups" --schedule daily --time-style daily
+./backup --dest "file:///backups" --schedule @daily --time-style daily
 ```
 
 When a schedule is provided, the tool:
@@ -69,6 +69,6 @@ When a schedule is provided, the tool:
 | `--property-root-path`| Root directory for the property catalog snapshots.                                     | `/tmp`                |
 | `--dest`            | Destination URL for backup data. (e.g., `file:///backups`)                                | _required_            |
 | `--time-style`      | Directory naming style based on time. Supports `daily` or `hourly`.                       | `daily`               |
-| `--schedule`        | Schedule style for periodic backup. If not set, backup is performed once. Options: `hourly` or `daily`. | _empty_               |
+| `--schedule`        | Schedule style for periodic backup. If not set, backup is performed once. Options: @yearly, @monthly, @weekly, @daily, @hourly and @every <duration>. | _empty_               |
 
 This guide should provide you with the necessary steps and information to effectively use the backup tool for your data backup operations.
diff --git a/docs/operation/restore.md b/docs/operation/restore.md
index 89ef4c26..0a77d8be 100644
--- a/docs/operation/restore.md
+++ b/docs/operation/restore.md
@@ -75,7 +75,7 @@ restore timedir create 2025-02-12 \
   --property-root /data
 ```
 
-This command writes the specified timestamp (e.g., 2025-02-12) into files named `stream-time-dir`, `measure-time-dir`, and `property-time-dir` in the designated root directories.
+This command writes the specified timestamp (e.g., 2025-02-12) into files named `/data/stream/time-dir`, `/data/measure/time-dir`, and `/data/property/time-dir` in the designated root directories.
 
 #### Verifying Timedir Files
 
@@ -108,7 +108,7 @@ restore run \
 
 **Key Points:**
 
-- The tool reads the timedir files (e.g., `stream-time-dir`) to fetch the appropriate timestamp.
+- The tool reads the timedir files (e.g., `/data/stream/time-dir`) to fetch the appropriate timestamp.
 - Local data is compared with the remote backup snapshot; orphaned files in local directories are removed.
 - Upon success, the timedir marker files are deleted to ensure a clean recovery state.
 
diff --git a/go.mod b/go.mod
index 8ab8f6f8..8c80c80a 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,7 @@ module github.com/apache/skywalking-banyandb
 
 go 1.23
 
-toolchain go1.23.5
+toolchain go1.23.6
 
 require (
 	github.com/RoaringBitmap/roaring v1.9.4
@@ -11,42 +11,42 @@ require (
 	github.com/blugelabs/bluge v0.2.2
 	github.com/cespare/xxhash/v2 v2.3.0
 	github.com/emirpasic/gods v1.18.1
-	github.com/envoyproxy/protoc-gen-validate v1.1.0
-	github.com/go-chi/chi/v5 v5.2.0
-	github.com/go-resty/resty/v2 v2.16.2
+	github.com/envoyproxy/protoc-gen-validate v1.2.1
+	github.com/go-chi/chi/v5 v5.2.1
+	github.com/go-resty/resty/v2 v2.16.5
 	github.com/google/go-cmp v0.6.0
 	github.com/google/uuid v1.6.0
 	github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
 	github.com/hashicorp/golang-lru v1.0.2
 	github.com/kkdai/maglev v0.2.0
 	github.com/montanaflynn/stats v0.7.1
 	github.com/oklog/run v1.1.0
-	github.com/onsi/ginkgo/v2 v2.22.1
-	github.com/onsi/gomega v1.36.1
+	github.com/onsi/ginkgo/v2 v2.22.2
+	github.com/onsi/gomega v1.36.2
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.20.5
 	github.com/rs/zerolog v1.33.0
 	github.com/spf13/cobra v1.8.1
-	github.com/spf13/pflag v1.0.5
+	github.com/spf13/pflag v1.0.6
 	github.com/spf13/viper v1.19.0
 	github.com/stretchr/testify v1.10.0
 	github.com/urfave/cli/v2 v2.27.5
 	github.com/xhit/go-str2duration/v2 v2.1.0
 	github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04
-	go.etcd.io/etcd/client/v3 v3.5.17
-	go.etcd.io/etcd/server/v3 v3.5.17
+	go.etcd.io/etcd/client/v3 v3.5.18
+	go.etcd.io/etcd/server/v3 v3.5.18
 	go.uber.org/automaxprocs v1.6.0
 	go.uber.org/mock v0.5.0
 	go.uber.org/multierr v1.11.0
-	golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67
-	golang.org/x/mod v0.22.0
-	google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb
-	google.golang.org/grpc v1.69.2
-	google.golang.org/protobuf v1.36.0
+	golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
+	golang.org/x/mod v0.23.0
+	google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b
+	google.golang.org/grpc v1.70.0
+	google.golang.org/protobuf v1.36.5
 	sigs.k8s.io/yaml v1.4.0
-	skywalking.apache.org/repo/goapi v0.0.0-20241129131257-944118bb91b8
+	skywalking.apache.org/repo/goapi v0.0.0-20241231024338-a68ffc997f46
 )
 
 require (
@@ -63,7 +63,7 @@ require (
 )
 
 require (
-	github.com/axiomhq/hyperloglog v0.2.2 // indirect
+	github.com/axiomhq/hyperloglog v0.2.3 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bits-and-blooms/bitset v1.20.0 // indirect
 	github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
@@ -79,7 +79,7 @@ require (
 	github.com/coreos/go-systemd/v22 v22.5.0 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/dchest/siphash v1.2.3 // indirect
-	github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
+	github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect
 	github.com/dustin/go-humanize v1.0.1
 	github.com/fsnotify/fsnotify v1.8.0 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
@@ -89,7 +89,7 @@ require (
 	github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
+	github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect
 	github.com/gorilla/websocket v1.5.3 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1
@@ -97,12 +97,12 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
-	github.com/jonboulle/clockwork v0.4.0 // indirect
+	github.com/jonboulle/clockwork v0.5.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/klauspost/compress v1.17.11
 	github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
 	github.com/magiconair/properties v1.8.9 // indirect
-	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -112,17 +112,17 @@ require (
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
-	github.com/prometheus/common v0.61.0 // indirect
+	github.com/prometheus/common v0.62.0 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
 	github.com/robfig/cron/v3 v3.0.1
-	github.com/sagikazarmark/locafero v0.6.0 // indirect
+	github.com/sagikazarmark/locafero v0.7.0 // indirect
 	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
 	github.com/shirou/gopsutil/v3 v3.24.5
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
 	github.com/soheilhy/cmux v0.1.5 // indirect
 	github.com/sourcegraph/conc v0.3.0 // indirect
-	github.com/spf13/afero v1.11.0 // indirect
+	github.com/spf13/afero v1.12.0 // indirect
 	github.com/spf13/cast v1.7.1 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/tklauser/go-sysconf v0.3.14 // indirect
@@ -130,28 +130,28 @@ require (
 	github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect
 	github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 // indirect
 	github.com/yusufpapurcu/wmi v1.2.4 // indirect
-	go.etcd.io/bbolt v1.3.11 // indirect
-	go.etcd.io/etcd/api/v3 v3.5.17
-	go.etcd.io/etcd/client/pkg/v3 v3.5.17
-	go.etcd.io/etcd/client/v2 v2.305.17 // indirect
-	go.etcd.io/etcd/pkg/v3 v3.5.17 // indirect
-	go.etcd.io/etcd/raft/v3 v3.5.17 // indirect
-	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
-	go.opentelemetry.io/otel v1.33.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
-	go.opentelemetry.io/otel/metric v1.33.0 // indirect
-	go.opentelemetry.io/otel/sdk v1.33.0 // indirect
-	go.opentelemetry.io/otel/trace v1.33.0 // indirect
-	go.opentelemetry.io/proto/otlp v1.4.0 // indirect
+	go.etcd.io/bbolt v1.4.0 // indirect
+	go.etcd.io/etcd/api/v3 v3.5.18
+	go.etcd.io/etcd/client/pkg/v3 v3.5.18
+	go.etcd.io/etcd/client/v2 v2.305.18 // indirect
+	go.etcd.io/etcd/pkg/v3 v3.5.18 // indirect
+	go.etcd.io/etcd/raft/v3 v3.5.18 // indirect
+	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
+	go.opentelemetry.io/otel v1.34.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
+	go.opentelemetry.io/otel/metric v1.34.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.34.0 // indirect
+	go.opentelemetry.io/otel/trace v1.34.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.5.0 // indirect
 	go.uber.org/zap v1.27.0
-	golang.org/x/crypto v0.31.0 // indirect
-	golang.org/x/net v0.33.0 // indirect
-	golang.org/x/sys v0.28.0
-	golang.org/x/text v0.21.0 // indirect
-	golang.org/x/time v0.8.0 // indirect
-	golang.org/x/tools v0.28.0 // indirect
-	google.golang.org/genproto v0.0.0-20241219192143-6b3ec007d9bb // indirect
+	golang.org/x/crypto v0.33.0 // indirect
+	golang.org/x/net v0.35.0 // indirect
+	golang.org/x/sys v0.30.0
+	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/time v0.10.0 // indirect
+	golang.org/x/tools v0.30.0 // indirect
+	google.golang.org/genproto v0.0.0-20250212204824-5a70512c5d8b // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0
diff --git a/go.sum b/go.sum
index e1b3faa1..86a95e21 100644
--- a/go.sum
+++ b/go.sum
@@ -18,8 +18,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/skywalking-cli v0.0.0-20240227151024-ee371a210afe h1:zIc2yfpc/vMpfTtWprCVpca6CMJwb6X9cknqAoFeEFo=
 github.com/apache/skywalking-cli v0.0.0-20240227151024-ee371a210afe/go.mod h1:pu6Q19Xs38FSfy/IwnJGAMilO+W58/ugM8aMfLzw+i0=
-github.com/axiomhq/hyperloglog v0.2.2 h1:9X9rOdYx82zXKgd1aMsDZNUw3d7DKAHhd2J305HZPA8=
-github.com/axiomhq/hyperloglog v0.2.2/go.mod h1:DLUK9yIzpU5B6YFLjxTIcbHu1g4Y1WQb1m5RH3radaM=
+github.com/axiomhq/hyperloglog v0.2.3 h1:2ZGwz3FGcx77e9/aNjqJijsGhH6RZOlglzxnDpVBCQY=
+github.com/axiomhq/hyperloglog v0.2.3/go.mod h1:DLUK9yIzpU5B6YFLjxTIcbHu1g4Y1WQb1m5RH3radaM=
 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -66,8 +66,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc
 github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
 github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
 github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
-github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
-github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
 github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
@@ -79,15 +79,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
-github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
+github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
 github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
 github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
 github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
 github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
-github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
+github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -98,8 +98,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
 github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
 github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
-github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg=
-github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU=
+github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
+github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
@@ -140,8 +140,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
-github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc=
+github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 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=
@@ -158,16 +158,16 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
 github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
 github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
-github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
+github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
+github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/kamstrup/intmap v0.5.1 h1:ENGAowczZA+PJPYYlreoqJvWgQVtAmX1l899WfYFVK0=
@@ -198,8 +198,9 @@ github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a
 github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
 github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
-github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -219,10 +220,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
 github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
-github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM=
-github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM=
-github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
-github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
+github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
+github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
+github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
 github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
@@ -241,8 +242,8 @@ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/j
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
-github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
+github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
@@ -255,8 +256,8 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
 github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
-github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
+github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
+github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
 github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
 github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
 github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
@@ -274,14 +275,15 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE
 github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
 github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
-github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
-github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
+github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
+github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
 github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
 github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
 github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
 github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
 github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -319,43 +321,43 @@ github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJ
 github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4=
 github.com/zinclabs/bluge_segment_api v1.0.0 h1:GJvPxdzR7KjwdxmcKleQLvtIYi/J7Q7ehRlZqgGayzg=
 github.com/zinclabs/bluge_segment_api v1.0.0/go.mod h1:mYfPVUdXLZ4iXsicXMER+RcI/avwphjMOi8nhN9HDLA=
-go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
-go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
-go.etcd.io/etcd/api/v3 v3.5.17 h1:cQB8eb8bxwuxOilBpMJAEo8fAONyrdXTHUNcMd8yT1w=
-go.etcd.io/etcd/api/v3 v3.5.17/go.mod h1:d1hvkRuXkts6PmaYk2Vrgqbv7H4ADfAKhyJqHNLJCB4=
-go.etcd.io/etcd/client/pkg/v3 v3.5.17 h1:XxnDXAWq2pnxqx76ljWwiQ9jylbpC4rvkAeRVOUKKVw=
-go.etcd.io/etcd/client/pkg/v3 v3.5.17/go.mod h1:4DqK1TKacp/86nJk4FLQqo6Mn2vvQFBmruW3pP14H/w=
-go.etcd.io/etcd/client/v2 v2.305.17 h1:ajFukQfI//xY5VuSeuUw4TJ4WnNR2kAFfV/P0pDdPMs=
-go.etcd.io/etcd/client/v2 v2.305.17/go.mod h1:EttKgEgvwikmXN+b7pkEWxDZr6sEaYsqCiS3k4fa/Vg=
-go.etcd.io/etcd/client/v3 v3.5.17 h1:o48sINNeWz5+pjy/Z0+HKpj/xSnBkuVhVvXkjEXbqZY=
-go.etcd.io/etcd/client/v3 v3.5.17/go.mod h1:j2d4eXTHWkT2ClBgnnEPm/Wuu7jsqku41v9DZ3OtjQo=
-go.etcd.io/etcd/pkg/v3 v3.5.17 h1:1k2wZ+oDp41jrk3F9o15o8o7K3/qliBo0mXqxo1PKaE=
-go.etcd.io/etcd/pkg/v3 v3.5.17/go.mod h1:FrztuSuaJG0c7RXCOzT08w+PCugh2kCQXmruNYCpCGA=
-go.etcd.io/etcd/raft/v3 v3.5.17 h1:wHPW/b1oFBw/+HjDAQ9vfr17OIInejTIsmwMZpK1dNo=
-go.etcd.io/etcd/raft/v3 v3.5.17/go.mod h1:uapEfOMPaJ45CqBYIraLO5+fqyIY2d57nFfxzFwy4D4=
-go.etcd.io/etcd/server/v3 v3.5.17 h1:xykBwLZk9IdDsB8z8rMdCCPRvhrG+fwvARaGA0TRiyc=
-go.etcd.io/etcd/server/v3 v3.5.17/go.mod h1:40sqgtGt6ZJNKm8nk8x6LexZakPu+NDl/DCgZTZ69Cc=
+go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
+go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
+go.etcd.io/etcd/api/v3 v3.5.18 h1:Q4oDAKnmwqTo5lafvB+afbgCDF7E35E4EYV2g+FNGhs=
+go.etcd.io/etcd/api/v3 v3.5.18/go.mod h1:uY03Ob2H50077J7Qq0DeehjM/A9S8PhVfbQ1mSaMopU=
+go.etcd.io/etcd/client/pkg/v3 v3.5.18 h1:mZPOYw4h8rTk7TeJ5+3udUkfVGBqc+GCjOJYd68QgNM=
+go.etcd.io/etcd/client/pkg/v3 v3.5.18/go.mod h1:BxVf2o5wXG9ZJV+/Cu7QNUiJYk4A29sAhoI5tIRsCu4=
+go.etcd.io/etcd/client/v2 v2.305.18 h1:jT7ANzlD47yu7t6ZGBr1trUDEN6P0RG9Wnyio6XP2Qo=
+go.etcd.io/etcd/client/v2 v2.305.18/go.mod h1:JikXfwJymsNv633PzkAb5xnVZmROgNWr4E68YCEz4jo=
+go.etcd.io/etcd/client/v3 v3.5.18 h1:nvvYmNHGumkDjZhTHgVU36A9pykGa2K4lAJ0yY7hcXA=
+go.etcd.io/etcd/client/v3 v3.5.18/go.mod h1:kmemwOsPU9broExyhYsBxX4spCTDX3yLgPMWtpBXG6E=
+go.etcd.io/etcd/pkg/v3 v3.5.18 h1:ny8rLA18/4AMdrILacOKwt7//TJjc7oS8JIJoLuNvbY=
+go.etcd.io/etcd/pkg/v3 v3.5.18/go.mod h1:gb4CDXuN/OgzUgj+VmUFumLYQ2FUMDC6r/plLIjHPI8=
+go.etcd.io/etcd/raft/v3 v3.5.18 h1:gueCda+9U76Lvk6rINjNc/mXalUp0u8OK5CVESDZh4I=
+go.etcd.io/etcd/raft/v3 v3.5.18/go.mod h1:XBaZHTJt3nLnpS8hMDR55Sxrq76cEC4xWYMBYSY3jcs=
+go.etcd.io/etcd/server/v3 v3.5.18 h1:u67DmyYyGOu08OiO9O3wgCSQEjGBNzjhH+FM3BcabcI=
+go.etcd.io/etcd/server/v3 v3.5.18/go.mod h1:waeL2uw6TdXniXaus105tiK1aSbblIBi21uk8y7D6Ng=
 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
-go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
-go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
-go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
-go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
-go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
-go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
-go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
-go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
-go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
-go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
+go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
+go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
-go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
+go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
+go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
 go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
@@ -375,11 +377,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
-golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
-golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
+golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
+golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
-golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
+golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs=
+golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -391,8 +393,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
-golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
+golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -411,8 +413,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
-golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
+golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
+golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -424,8 +426,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
-golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -452,8 +454,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -467,10 +469,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
-golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
+golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -484,8 +486,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
-golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
+golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
+golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -500,12 +502,12 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20241219192143-6b3ec007d9bb h1:JGs+s1Q6osip3cDY197L1HmkuPn8wPp9Hfy9jl+Uz+U=
-google.golang.org/genproto v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:o8GgNarfULyZPNaIY8RDfXM7AZcmcKC/tbMWp/ZOFDw=
-google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb h1:B7GIB7sr443wZ/EAEl7VZjmh1V6qzkt5V+RYcUYtS1U=
-google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:E5//3O5ZIG2l71Xnt+P/CYUY8Bxs8E7WMoZ9tlcMbAY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb h1:3oy2tynMOP1QbTC0MsNNAV+Se8M2Bd0A5+x1QHyw+pI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
+google.golang.org/genproto v0.0.0-20250212204824-5a70512c5d8b h1:TdBaFxGAABTI8sz9jYHPtjje677pS4XXup9vJMlj8hQ=
+google.golang.org/genproto v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:0TrvLFkilZy+XULmuoWfiTbTRXLWXJ1S44jQTW3lWwE=
+google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b h1:i+d0RZa8Hs2L/MuaOQYI+krthcxdEbEM2N+Tf3kJ4zk=
+google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
@@ -515,8 +517,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
-google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
+google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
+google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -529,8 +531,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
-google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
-google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
+google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
@@ -552,5 +554,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
 sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
-skywalking.apache.org/repo/goapi v0.0.0-20241129131257-944118bb91b8 h1:JkgizChUyT1mobFo2I3lI8+qsQU22i3FdxR0BSFC0uw=
-skywalking.apache.org/repo/goapi v0.0.0-20241129131257-944118bb91b8/go.mod h1:+n8BMuS8eRdzdnGh15ElRGBXPi0eYZSs2TKySBDmRTE=
+skywalking.apache.org/repo/goapi v0.0.0-20241231024338-a68ffc997f46 h1:Lb9cumKH17PWZSs6BKT91dbwJAl1jCvYO7EQMM9yFTw=
+skywalking.apache.org/repo/goapi v0.0.0-20241231024338-a68ffc997f46/go.mod h1:+n8BMuS8eRdzdnGh15ElRGBXPi0eYZSs2TKySBDmRTE=
diff --git a/scripts/build/build.mk b/scripts/build/build.mk
index 899dfef0..87160cd5 100644
--- a/scripts/build/build.mk
+++ b/scripts/build/build.mk
@@ -69,7 +69,7 @@ $(SLIM_BINARIES_GOBUILD_TARGET): $(BUILD_DIR)/$(OS)/%-slim: $(BUILD_LOCK)
 	$(call set_build_package,$*,$@)
 	@echo "Building slim $*"
 	$(MAKE) prepare-build
-	$(eval BUILD_TAGS := $(BUILD_TAGS) slim)
+	$(if $(filter slim,$(BUILD_TAGS)),, $(eval BUILD_TAGS := $(BUILD_TAGS) slim))
 	$(call go_build_static_executable,,-s -w)
 	@echo "Done building static $*"
 
diff --git a/scripts/build/version.mk b/scripts/build/version.mk
index 21cec959..4b350d83 100644
--- a/scripts/build/version.mk
+++ b/scripts/build/version.mk
@@ -29,6 +29,6 @@ LICENSE_EYE_VERSION := 3ea9df11bb3a5a85665377d1fd10c02edecf2c40
 
 MOCKGEN_VERSION := v0.4.0
 
-GINKGO_VERSION := v2.22.1
+GINKGO_VERSION := v2.22.2
 
 GOVULNCHECK_VERSION := v1.1.3
diff --git a/scripts/ci/check/version_test.go b/scripts/ci/check/version_test.go
index a5855cb5..e20646bf 100644
--- a/scripts/ci/check/version_test.go
+++ b/scripts/ci/check/version_test.go
@@ -31,7 +31,7 @@ import (
 )
 
 const (
-	GoVersion = "1.23.5"
+	GoVersion = "1.23.6"
 	CPUType   = 8
 )
 
diff --git a/test/cases/backup/all.go b/test/cases/backup/all.go
index b155c9bd..8ec42c89 100644
--- a/test/cases/backup/all.go
+++ b/test/cases/backup/all.go
@@ -26,7 +26,7 @@ import (
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 
-	"github.com/apache/skywalking-banyandb/bydbbackup/pkg"
+	"github.com/apache/skywalking-banyandb/banyand/backup"
 )
 
 var _ = ginkgo.Describe("Backup All", func() {
@@ -38,7 +38,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 			defer os.RemoveAll(destDir)
 			destURL := "file://" + destDir
 
-			backupCmd := pkg.NewBackupCommand()
+			backupCmd := backup.NewBackupCommand()
 			backupCmd.SetArgs([]string{
 				"--grpc-addr", SharedContext.DataAddr,
 				"--stream-root-path", SharedContext.RootDir,
@@ -66,7 +66,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 			gomega.Expect(err).NotTo(gomega.HaveOccurred())
 			defer os.RemoveAll(newCatalogDir)
 
-			listCmd := pkg.NewTimeDirCommand()
+			listCmd := backup.NewTimeDirCommand()
 			listCmd.SetArgs([]string{"list", "--dest", destURL})
 			listOut := &bytes.Buffer{}
 			listCmd.SetOut(listOut)
@@ -90,7 +90,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 			gomega.Expect(latestTimedir).To(gomega.Equal(backupTimeDir))
 
 			ginkgo.By("Create timedir in new catalog's root path")
-			createCmd := pkg.NewTimeDirCommand()
+			createCmd := backup.NewTimeDirCommand()
 			createCmd.SetArgs([]string{
 				"create",
 				"--stream-root", newCatalogDir,
@@ -105,7 +105,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 			gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 			ginkgo.By("Read timedir from new catalog's root path")
-			readCmd := pkg.NewTimeDirCommand()
+			readCmd := backup.NewTimeDirCommand()
 			readCmd.SetArgs([]string{
 				"read",
 				"--stream-root", newCatalogDir,
@@ -132,7 +132,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 			}
 
 			ginkgo.By("Restore data from the remote destination")
-			restoreCmd := pkg.NewRestoreCommand()
+			restoreCmd := backup.NewRestoreCommand()
 			restoreCmd.SetArgs([]string{
 				"run",
 				"--source", destURL,
@@ -167,7 +167,7 @@ var _ = ginkgo.Describe("Backup All", func() {
 
 			// Verify that the timedir file is removed from the new catalog's root path (after a successful restore).
 			for _, cat := range catalogs {
-				timedirFile := filepath.Join(newCatalogDir, cat+"-time-dir")
+				timedirFile := filepath.Join(newCatalogDir, cat, "time-dir")
 				_, err = os.Stat(timedirFile)
 				gomega.Expect(os.IsNotExist(err)).To(gomega.BeTrue())
 			}
diff --git a/test/cases/backup/backup.go b/test/cases/backup/backup.go
index f78a5999..c3a9c53a 100644
--- a/test/cases/backup/backup.go
+++ b/test/cases/backup/backup.go
@@ -29,7 +29,7 @@ import (
 
 	commonv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/common/v1"
 	databasev1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/database/v1"
-	"github.com/apache/skywalking-banyandb/bydbbackup/pkg"
+	"github.com/apache/skywalking-banyandb/banyand/backup"
 	"github.com/apache/skywalking-banyandb/pkg/fs"
 	"github.com/apache/skywalking-banyandb/pkg/test/helpers"
 )
@@ -100,7 +100,7 @@ var _ = ginkgo.Describe("Backup", func() {
 		defer os.RemoveAll(destDir)
 		destURL := "file://" + destDir
 
-		backupCmd := pkg.NewBackupCommand()
+		backupCmd := backup.NewBackupCommand()
 		backupCmd.SetArgs([]string{
 			"--grpc-addr", SharedContext.DataAddr,
 			"--stream-root-path", SharedContext.RootDir,
diff --git a/ui/LICENSE b/ui/LICENSE
index 604f1959..b21f9a14 100644
--- a/ui/LICENSE
+++ b/ui/LICENSE
@@ -17,7 +17,7 @@ Apache-2.0 licenses
 ========================================================================
 
     detect-libc 1.0.3 Apache-2.0
-    echarts 5.5.1 Apache-2.0
+    echarts 5.6.0 Apache-2.0
 
 ========================================================================
 BSD-2-Clause licenses
@@ -31,7 +31,7 @@ BSD-3-Clause licenses
 
     normalize-wheel-es 1.2.0 BSD-3-Clause
     source-map-js 1.2.1 BSD-3-Clause
-    zrender 5.6.0 BSD-3-Clause
+    zrender 5.6.1 BSD-3-Clause
 
 ========================================================================
 ISC licenses
@@ -39,8 +39,8 @@ ISC licenses
 
     graceful-fs 4.2.11 ISC
     picocolors 1.1.1 ISC
-    semver 7.6.3 ISC
-    yaml 2.6.1 ISC
+    semver 7.7.1 ISC
+    yaml 2.7.0 ISC
 
 ========================================================================
 MIT licenses
@@ -48,19 +48,19 @@ MIT licenses
 
     @babel/helper-string-parser 7.25.9 MIT
     @babel/helper-validator-identifier 7.25.9 MIT
-    @babel/parser 7.26.3 MIT
-    @babel/types 7.26.3 MIT
+    @babel/parser 7.26.8 MIT
+    @babel/types 7.26.8 MIT
     @ctrl/tinycolor 3.6.1 MIT
     @element-plus/icons-vue 2.3.1 MIT
-    @floating-ui/core 1.6.8 MIT
-    @floating-ui/dom 1.6.12 MIT
-    @floating-ui/utils 0.2.8 MIT
+    @floating-ui/core 1.6.9 MIT
+    @floating-ui/dom 1.6.13 MIT
+    @floating-ui/utils 0.2.9 MIT
     @jridgewell/sourcemap-codec 1.5.0 MIT
-    @parcel/watcher 2.5.0 MIT
-    @parcel/watcher-linux-x64-glibc 2.5.0 MIT
-    @parcel/watcher-linux-x64-musl 2.5.0 MIT
+    @parcel/watcher 2.5.1 MIT
+    @parcel/watcher-linux-x64-glibc 2.5.1 MIT
+    @parcel/watcher-linux-x64-musl 2.5.1 MIT
     @popperjs/core 2.11.7 MIT
-    @types/lodash 4.17.13 MIT
+    @types/lodash 4.17.15 MIT
     @types/lodash-es 4.17.12 MIT
     @types/web-bluetooth 0.0.16 MIT
     @vue/compiler-core 3.5.13 MIT
@@ -86,7 +86,7 @@ MIT licenses
     csstype 3.1.3 MIT
     dayjs 1.11.13 MIT
     delayed-stream 1.0.0 MIT
-    element-plus 2.9.1 MIT
+    element-plus 2.9.4 MIT
     escape-html 1.0.3 MIT
     estree-walker 2.0.2 MIT
     fill-range 7.1.1 MIT
@@ -110,11 +110,11 @@ MIT licenses
     nanoid 3.3.8 MIT
     node-addon-api 7.1.1 MIT
     picomatch 2.3.1 MIT
-    pinia 2.3.0 MIT
-    postcss 8.4.49 MIT
+    pinia 2.3.1 MIT
+    postcss 8.5.2 MIT
     proxy-from-env 1.1.0 MIT
-    readdirp 4.0.2 MIT
-    sass 1.83.0 MIT
+    readdirp 4.1.1 MIT
+    sass 1.84.0 MIT
     to-regex-range 5.0.1 MIT
     universalify 2.0.1 MIT
     vue 3.5.13 MIT
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 7d601a89..22188347 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -63,12 +63,12 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.26.3",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz",
-      "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==",
+      "version": "7.26.8",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz",
+      "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.26.3"
+        "@babel/types": "^7.26.8"
       },
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -78,9 +78,9 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.26.3",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz",
-      "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==",
+      "version": "7.26.8",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz",
+      "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-string-parser": "^7.25.9",
@@ -500,28 +500,28 @@
       }
     },
     "node_modules/@floating-ui/core": {
-      "version": "1.6.8",
-      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
-      "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
+      "version": "1.6.9",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
+      "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
       "license": "MIT",
       "dependencies": {
-        "@floating-ui/utils": "^0.2.8"
+        "@floating-ui/utils": "^0.2.9"
       }
     },
     "node_modules/@floating-ui/dom": {
-      "version": "1.6.12",
-      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
-      "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
+      "version": "1.6.13",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
+      "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
       "license": "MIT",
       "dependencies": {
         "@floating-ui/core": "^1.6.0",
-        "@floating-ui/utils": "^0.2.8"
+        "@floating-ui/utils": "^0.2.9"
       }
     },
     "node_modules/@floating-ui/utils": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
-      "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
+      "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
       "license": "MIT"
     },
     "node_modules/@jridgewell/sourcemap-codec": {
@@ -569,9 +569,9 @@
       }
     },
     "node_modules/@parcel/watcher": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz",
-      "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
+      "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
       "hasInstallScript": true,
       "license": "MIT",
       "optional": true,
@@ -589,25 +589,25 @@
         "url": "https://opencollective.com/parcel"
       },
       "optionalDependencies": {
-        "@parcel/watcher-android-arm64": "2.5.0",
-        "@parcel/watcher-darwin-arm64": "2.5.0",
-        "@parcel/watcher-darwin-x64": "2.5.0",
-        "@parcel/watcher-freebsd-x64": "2.5.0",
-        "@parcel/watcher-linux-arm-glibc": "2.5.0",
-        "@parcel/watcher-linux-arm-musl": "2.5.0",
-        "@parcel/watcher-linux-arm64-glibc": "2.5.0",
-        "@parcel/watcher-linux-arm64-musl": "2.5.0",
-        "@parcel/watcher-linux-x64-glibc": "2.5.0",
-        "@parcel/watcher-linux-x64-musl": "2.5.0",
-        "@parcel/watcher-win32-arm64": "2.5.0",
-        "@parcel/watcher-win32-ia32": "2.5.0",
-        "@parcel/watcher-win32-x64": "2.5.0"
+        "@parcel/watcher-android-arm64": "2.5.1",
+        "@parcel/watcher-darwin-arm64": "2.5.1",
+        "@parcel/watcher-darwin-x64": "2.5.1",
+        "@parcel/watcher-freebsd-x64": "2.5.1",
+        "@parcel/watcher-linux-arm-glibc": "2.5.1",
+        "@parcel/watcher-linux-arm-musl": "2.5.1",
+        "@parcel/watcher-linux-arm64-glibc": "2.5.1",
+        "@parcel/watcher-linux-arm64-musl": "2.5.1",
+        "@parcel/watcher-linux-x64-glibc": "2.5.1",
+        "@parcel/watcher-linux-x64-musl": "2.5.1",
+        "@parcel/watcher-win32-arm64": "2.5.1",
+        "@parcel/watcher-win32-ia32": "2.5.1",
+        "@parcel/watcher-win32-x64": "2.5.1"
       }
     },
     "node_modules/@parcel/watcher-android-arm64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz",
-      "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
+      "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
       "cpu": [
         "arm64"
       ],
@@ -625,9 +625,9 @@
       }
     },
     "node_modules/@parcel/watcher-darwin-arm64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz",
-      "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
+      "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
       "cpu": [
         "arm64"
       ],
@@ -645,9 +645,9 @@
       }
     },
     "node_modules/@parcel/watcher-darwin-x64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz",
-      "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
+      "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
       "cpu": [
         "x64"
       ],
@@ -665,9 +665,9 @@
       }
     },
     "node_modules/@parcel/watcher-freebsd-x64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz",
-      "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
+      "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
       "cpu": [
         "x64"
       ],
@@ -685,9 +685,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-arm-glibc": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz",
-      "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
+      "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
       "cpu": [
         "arm"
       ],
@@ -705,9 +705,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-arm-musl": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz",
-      "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
+      "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
       "cpu": [
         "arm"
       ],
@@ -725,9 +725,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-arm64-glibc": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz",
-      "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
+      "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
       "cpu": [
         "arm64"
       ],
@@ -745,9 +745,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-arm64-musl": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz",
-      "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
+      "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
       "cpu": [
         "arm64"
       ],
@@ -765,9 +765,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-x64-glibc": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz",
-      "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
+      "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
       "cpu": [
         "x64"
       ],
@@ -785,9 +785,9 @@
       }
     },
     "node_modules/@parcel/watcher-linux-x64-musl": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz",
-      "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
+      "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
       "cpu": [
         "x64"
       ],
@@ -805,9 +805,9 @@
       }
     },
     "node_modules/@parcel/watcher-win32-arm64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz",
-      "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
+      "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
       "cpu": [
         "arm64"
       ],
@@ -825,9 +825,9 @@
       }
     },
     "node_modules/@parcel/watcher-win32-ia32": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz",
-      "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
+      "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
       "cpu": [
         "ia32"
       ],
@@ -845,9 +845,9 @@
       }
     },
     "node_modules/@parcel/watcher-win32-x64": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz",
-      "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==",
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
+      "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
       "cpu": [
         "x64"
       ],
@@ -912,9 +912,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
-      "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz",
+      "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==",
       "cpu": [
         "arm"
       ],
@@ -926,9 +926,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz",
-      "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz",
+      "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==",
       "cpu": [
         "arm64"
       ],
@@ -940,9 +940,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz",
-      "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz",
+      "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==",
       "cpu": [
         "arm64"
       ],
@@ -954,9 +954,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz",
-      "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz",
+      "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==",
       "cpu": [
         "x64"
       ],
@@ -968,9 +968,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-arm64": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz",
-      "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz",
+      "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==",
       "cpu": [
         "arm64"
       ],
@@ -982,9 +982,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-x64": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz",
-      "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz",
+      "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==",
       "cpu": [
         "x64"
       ],
@@ -996,9 +996,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz",
-      "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz",
+      "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==",
       "cpu": [
         "arm"
       ],
@@ -1010,9 +1010,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz",
-      "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz",
+      "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==",
       "cpu": [
         "arm"
       ],
@@ -1024,9 +1024,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz",
-      "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz",
+      "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==",
       "cpu": [
         "arm64"
       ],
@@ -1038,9 +1038,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz",
-      "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz",
+      "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==",
       "cpu": [
         "arm64"
       ],
@@ -1052,9 +1052,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz",
-      "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz",
+      "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==",
       "cpu": [
         "loong64"
       ],
@@ -1066,9 +1066,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz",
-      "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz",
+      "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==",
       "cpu": [
         "ppc64"
       ],
@@ -1080,9 +1080,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz",
-      "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz",
+      "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==",
       "cpu": [
         "riscv64"
       ],
@@ -1094,9 +1094,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz",
-      "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz",
+      "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==",
       "cpu": [
         "s390x"
       ],
@@ -1108,9 +1108,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz",
-      "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz",
+      "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==",
       "cpu": [
         "x64"
       ],
@@ -1122,9 +1122,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz",
-      "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz",
+      "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==",
       "cpu": [
         "x64"
       ],
@@ -1136,9 +1136,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz",
-      "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz",
+      "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==",
       "cpu": [
         "arm64"
       ],
@@ -1150,9 +1150,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz",
-      "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz",
+      "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==",
       "cpu": [
         "ia32"
       ],
@@ -1164,9 +1164,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz",
-      "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz",
+      "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==",
       "cpu": [
         "x64"
       ],
@@ -1185,9 +1185,9 @@
       "license": "MIT"
     },
     "node_modules/@types/lodash": {
-      "version": "4.17.13",
-      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz",
-      "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==",
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz",
+      "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==",
       "license": "MIT"
     },
     "node_modules/@types/lodash-es": {
@@ -1553,19 +1553,19 @@
       }
     },
     "node_modules/echarts": {
-      "version": "5.5.1",
-      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.1.tgz",
-      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz",
+      "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==",
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "2.3.0",
-        "zrender": "5.6.0"
+        "zrender": "5.6.1"
       }
     },
     "node_modules/element-plus": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.9.1.tgz",
-      "integrity": "sha512-9Agqf/jt4Ugk7EZ6C5LME71sgkvauPCsnvJN12Xid2XVobjufxMGpRE4L7pS4luJMOmFAH3J0NgYEGZT5r+NDg==",
+      "version": "2.9.4",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.9.4.tgz",
+      "integrity": "sha512-sGnW0wd9zf6lEGixXV2gfwx3X6VTMkP52qTkX7zbURJ2oariyslrKTBh2txt1sdn1pUvj2l0KY3OfSXoZGmDOw==",
       "license": "MIT",
       "dependencies": {
         "@ctrl/tinycolor": "^3.4.1",
@@ -1665,9 +1665,9 @@
       "license": "MIT"
     },
     "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -1675,16 +1675,16 @@
         "@nodelib/fs.walk": "^1.2.3",
         "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
+        "micromatch": "^4.0.8"
       },
       "engines": {
         "node": ">=8.6.0"
       }
     },
     "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
+      "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
       "dev": true,
       "license": "ISC",
       "dependencies": {
@@ -1816,9 +1816,9 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.16.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
-      "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
+      "version": "2.16.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2018,15 +2018,15 @@
       "license": "MIT"
     },
     "node_modules/mlly": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz",
-      "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==",
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+      "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "acorn": "^8.14.0",
-        "pathe": "^1.1.2",
-        "pkg-types": "^1.2.1",
+        "pathe": "^2.0.1",
+        "pkg-types": "^1.3.0",
         "ufo": "^1.5.4"
       }
     },
@@ -2086,9 +2086,9 @@
       "license": "MIT"
     },
     "node_modules/pathe": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
-      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+      "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
       "dev": true,
       "license": "MIT"
     },
@@ -2112,9 +2112,9 @@
       }
     },
     "node_modules/pinia": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.0.tgz",
-      "integrity": "sha512-ohZj3jla0LL0OH5PlLTDMzqKiVw2XARmC1XYLdLWIPBMdhDW/123ZWr4zVAhtJm+aoSkFa13pYXskAvAscIkhQ==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
+      "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
       "license": "MIT",
       "dependencies": {
         "@vue/devtools-api": "^6.6.3",
@@ -2134,21 +2134,21 @@
       }
     },
     "node_modules/pkg-types": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz",
-      "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==",
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+      "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "confbox": "^0.1.8",
-        "mlly": "^1.7.2",
-        "pathe": "^1.1.2"
+        "mlly": "^1.7.4",
+        "pathe": "^2.0.1"
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.49",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
-      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+      "version": "8.5.2",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
+      "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
       "funding": [
         {
           "type": "opencollective",
@@ -2165,7 +2165,7 @@
       ],
       "license": "MIT",
       "dependencies": {
-        "nanoid": "^3.3.7",
+        "nanoid": "^3.3.8",
         "picocolors": "^1.1.1",
         "source-map-js": "^1.2.1"
       },
@@ -2174,9 +2174,9 @@
       }
     },
     "node_modules/prettier": {
-      "version": "3.4.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
-      "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.0.tgz",
+      "integrity": "sha512-quyMrVt6svPS7CjQ9gKb3GLEX/rl3BCL2oa/QkNcXv4YNVBC9olt3s+H7ukto06q7B1Qz46PbrKLO34PR6vXcA==",
       "dev": true,
       "license": "MIT",
       "bin": {
@@ -2217,12 +2217,12 @@
       "license": "MIT"
     },
     "node_modules/readdirp": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
-      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
+      "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
       "license": "MIT",
       "engines": {
-        "node": ">= 14.16.0"
+        "node": ">= 14.18.0"
       },
       "funding": {
         "type": "individual",
@@ -2262,9 +2262,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.29.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz",
-      "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==",
+      "version": "4.34.6",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz",
+      "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2278,25 +2278,25 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.29.1",
-        "@rollup/rollup-android-arm64": "4.29.1",
-        "@rollup/rollup-darwin-arm64": "4.29.1",
-        "@rollup/rollup-darwin-x64": "4.29.1",
-        "@rollup/rollup-freebsd-arm64": "4.29.1",
-        "@rollup/rollup-freebsd-x64": "4.29.1",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
-        "@rollup/rollup-linux-arm-musleabihf": "4.29.1",
-        "@rollup/rollup-linux-arm64-gnu": "4.29.1",
-        "@rollup/rollup-linux-arm64-musl": "4.29.1",
-        "@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
-        "@rollup/rollup-linux-riscv64-gnu": "4.29.1",
-        "@rollup/rollup-linux-s390x-gnu": "4.29.1",
-        "@rollup/rollup-linux-x64-gnu": "4.29.1",
-        "@rollup/rollup-linux-x64-musl": "4.29.1",
-        "@rollup/rollup-win32-arm64-msvc": "4.29.1",
-        "@rollup/rollup-win32-ia32-msvc": "4.29.1",
-        "@rollup/rollup-win32-x64-msvc": "4.29.1",
+        "@rollup/rollup-android-arm-eabi": "4.34.6",
+        "@rollup/rollup-android-arm64": "4.34.6",
+        "@rollup/rollup-darwin-arm64": "4.34.6",
+        "@rollup/rollup-darwin-x64": "4.34.6",
+        "@rollup/rollup-freebsd-arm64": "4.34.6",
+        "@rollup/rollup-freebsd-x64": "4.34.6",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.34.6",
+        "@rollup/rollup-linux-arm-musleabihf": "4.34.6",
+        "@rollup/rollup-linux-arm64-gnu": "4.34.6",
+        "@rollup/rollup-linux-arm64-musl": "4.34.6",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.34.6",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6",
+        "@rollup/rollup-linux-riscv64-gnu": "4.34.6",
+        "@rollup/rollup-linux-s390x-gnu": "4.34.6",
+        "@rollup/rollup-linux-x64-gnu": "4.34.6",
+        "@rollup/rollup-linux-x64-musl": "4.34.6",
+        "@rollup/rollup-win32-arm64-msvc": "4.34.6",
+        "@rollup/rollup-win32-ia32-msvc": "4.34.6",
+        "@rollup/rollup-win32-x64-msvc": "4.34.6",
         "fsevents": "~2.3.2"
       }
     },
@@ -2325,9 +2325,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.83.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.0.tgz",
-      "integrity": "sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==",
+      "version": "1.84.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.84.0.tgz",
+      "integrity": "sha512-XDAbhEPJRxi7H0SxrnOpiXFQoUJHwkR2u3Zc4el+fK/Tt5Hpzw5kkQ59qVDfvdaUq6gCrEZIbySFBM2T9DNKHg==",
       "license": "MIT",
       "dependencies": {
         "chokidar": "^4.0.0",
@@ -2352,9 +2352,9 @@
       "license": "MIT"
     },
     "node_modules/semver": {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
-      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+      "version": "7.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+      "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
@@ -2425,26 +2425,26 @@
       "license": "MIT"
     },
     "node_modules/unimport": {
-      "version": "3.14.5",
-      "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.14.5.tgz",
-      "integrity": "sha512-tn890SwFFZxqaJSKQPPd+yygfKSATbM8BZWW1aCR2TJBTs1SDrmLamBueaFtYsGjHtQaRgqEbQflOjN2iW12gA==",
+      "version": "3.14.6",
+      "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.14.6.tgz",
+      "integrity": "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@rollup/pluginutils": "^5.1.3",
+        "@rollup/pluginutils": "^5.1.4",
         "acorn": "^8.14.0",
         "escape-string-regexp": "^5.0.0",
         "estree-walker": "^3.0.3",
-        "fast-glob": "^3.3.2",
-        "local-pkg": "^0.5.1",
-        "magic-string": "^0.30.14",
-        "mlly": "^1.7.3",
-        "pathe": "^1.1.2",
+        "fast-glob": "^3.3.3",
+        "local-pkg": "^1.0.0",
+        "magic-string": "^0.30.17",
+        "mlly": "^1.7.4",
+        "pathe": "^2.0.1",
         "picomatch": "^4.0.2",
-        "pkg-types": "^1.2.1",
+        "pkg-types": "^1.3.0",
         "scule": "^1.3.0",
         "strip-literal": "^2.1.1",
-        "unplugin": "^1.16.0"
+        "unplugin": "^1.16.1"
       }
     },
     "node_modules/unimport/node_modules/estree-walker": {
@@ -2457,6 +2457,23 @@
         "@types/estree": "^1.0.0"
       }
     },
+    "node_modules/unimport/node_modules/local-pkg": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.0.0.tgz",
+      "integrity": "sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mlly": "^1.7.3",
+        "pkg-types": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
     "node_modules/unimport/node_modules/picomatch": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
@@ -2480,9 +2497,9 @@
       }
     },
     "node_modules/unplugin": {
-      "version": "1.16.0",
-      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.0.tgz",
-      "integrity": "sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==",
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
+      "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2747,9 +2764,9 @@
       "license": "MIT"
     },
     "node_modules/yaml": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
-      "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+      "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
       "license": "ISC",
       "bin": {
         "yaml": "bin.mjs"
@@ -2759,9 +2776,9 @@
       }
     },
     "node_modules/zrender": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz",
-      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz",
+      "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==",
       "license": "BSD-3-Clause",
       "dependencies": {
         "tslib": "2.3.0"
diff --git a/ui/src/styles/custom.scss b/ui/src/styles/custom.scss
index cd527ff4..e57d9575 100644
--- a/ui/src/styles/custom.scss
+++ b/ui/src/styles/custom.scss
@@ -57,6 +57,6 @@ html {
   --size-lt: 1.1em;
   --size-title: 1.2em;
   --size-big: 1.4em;
-  --font-family-main: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana,
-    sans-serif;
+  --font-family-main:
+    'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
 }