From ef52cf383f1c90f8364e00b0a73810cc396a2def Mon Sep 17 00:00:00 2001
From: Alexander Trost <galexrt@googlemail.com>
Date: Sun, 5 Jan 2025 23:35:53 +0100
Subject: [PATCH] feat: allow grpc api traffic via the gin http server

Signed-off-by: Alexander Trost <galexrt@googlemail.com>
---
 .vscode/launch.json                    |   1 +
 config.example.yaml                    |   6 +-
 gen/go/proto/services/sync/data.go     |  11 +
 gen/go/proto/services/sync/sync.go     |  13 +-
 go.mod                                 |   2 +-
 go.sum                                 |   4 +-
 go.work.sum                            |   2 +
 internal/modules/tests_grpc.go         |   4 +
 internal/tests/certs/gen_cert.sh       |   7 +-
 internal/tests/certs/localhost.crt     |  64 +--
 internal/tests/certs/localhost.key     |  79 ++--
 internal/tests/certs/localhostCA.conf  |   2 +-
 internal/tests/certs/localhostCA.key   |  54 +++
 internal/tests/certs/localhostCA.pem   |  59 +--
 internal/tests/certs/localhostCA.srl   |   1 +
 package.json                           |  11 +-
 pkg/config/config.go                   |   9 +-
 pkg/dbsync/client_auth.go              |  18 +
 pkg/dbsync/sync.go                     |  20 +
 pkg/dbsync/sync_jobs.go                |  39 ++
 pkg/dbsync/{users.go => sync_users.go} |  19 +-
 pkg/dbsync/types.go                    |   3 +-
 pkg/grpc/auth/client_token.go          |  24 ++
 pkg/grpc/grpcws/README.md              |   2 +-
 pkg/grpc/grpcws/client/client_test.go  | 144 +++++++
 pkg/grpc/grpcws/websocket_channel.go   |   1 -
 pkg/grpc/server.go                     |   4 +
 pkg/server/http.go                     |  38 +-
 pnpm-lock.yaml                         | 537 +++++++++++++++----------
 29 files changed, 857 insertions(+), 321 deletions(-)
 create mode 100644 gen/go/proto/services/sync/data.go
 create mode 100644 internal/tests/certs/localhostCA.key
 create mode 100644 internal/tests/certs/localhostCA.srl
 create mode 100644 pkg/dbsync/client_auth.go
 create mode 100644 pkg/dbsync/sync_jobs.go
 rename pkg/dbsync/{users.go => sync_users.go} (76%)
 create mode 100644 pkg/grpc/auth/client_token.go
 create mode 100644 pkg/grpc/grpcws/client/client_test.go

diff --git a/.vscode/launch.json b/.vscode/launch.json
index d7f4b5b2a..2a69e453b 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -75,6 +75,7 @@
             "buildFlags": "-race -a -installsuffix cgo",
             "env": {
                 "CGO_ENABLED": "1",
+                "FIVENET_CONFIG_FILE": "./config.worker.yaml",
                 "FIVENET_DBSYNC_FILE": "./dbsync.yaml"
             },
             "dlvFlags": ["--check-go-version=false"]
diff --git a/config.example.yaml b/config.example.yaml
index 0ccabf856..9b9df46ed 100644
--- a/config.example.yaml
+++ b/config.example.yaml
@@ -98,8 +98,6 @@ auth:
     - projektleiter
     - teamleitung
   superuserUsers: []
-  syncAPITokens: []
-    #- LONG_RANDOM_API_TOKEN_FOR_DBSYNC
 dispatchCenter:
   convertJobs: []
     #- police
@@ -131,3 +129,7 @@ game:
   # First grade "number/id", some servers start at 0, but I have seen some start at 1
   startJobGrade: 0
   defaultLocale: "en"
+sync:
+  enabled: false
+  apiTokens: []
+    #- LONG_RANDOM_API_TOKEN_FOR_DBSYNC
diff --git a/gen/go/proto/services/sync/data.go b/gen/go/proto/services/sync/data.go
new file mode 100644
index 000000000..01f8fc84a
--- /dev/null
+++ b/gen/go/proto/services/sync/data.go
@@ -0,0 +1,11 @@
+package sync
+
+import "context"
+
+func (s *Server) SyncData(ctx context.Context, req *SyncDataRequest) (*SyncDataResponse, error) {
+	// TODO handle sync data request
+
+	return &SyncDataResponse{
+		AffectedRows: 0,
+	}, nil
+}
diff --git a/gen/go/proto/services/sync/sync.go b/gen/go/proto/services/sync/sync.go
index 712d5fe2d..47d8276ca 100644
--- a/gen/go/proto/services/sync/sync.go
+++ b/gen/go/proto/services/sync/sync.go
@@ -33,12 +33,16 @@ type Params struct {
 }
 
 func NewServer(p Params) *Server {
+	if !p.Config.Sync.Enabled {
+		return nil
+	}
+
 	return &Server{
 		logger: p.Logger,
 		db:     p.DB,
 		auth:   p.Auth,
 
-		tokens: p.Config.Auth.SyncAPITokens,
+		tokens: p.Config.Sync.APITokens,
 	}
 }
 
@@ -67,8 +71,7 @@ func (s *Server) AuthFuncOverride(ctx context.Context, fullMethod string) (conte
 	return ctx, nil
 }
 
-func (s *Server) SyncData(ctx context.Context, req *SyncDataRequest) (*SyncDataResponse, error) {
-	// TODO handle sync data request
-
-	return nil, nil
+func (s *Server) PermissionUnaryFuncOverride(ctx context.Context, info *grpc.UnaryServerInfo) (context.Context, error) {
+	// Skip permission check for the sync service
+	return ctx, nil
 }
diff --git a/go.mod b/go.mod
index b82b18af1..8b349422f 100644
--- a/go.mod
+++ b/go.mod
@@ -67,7 +67,7 @@ require (
 	golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67
 	golang.org/x/image v0.23.0
 	golang.org/x/net v0.33.0
-	golang.org/x/oauth2 v0.24.0
+	golang.org/x/oauth2 v0.25.0
 	golang.org/x/text v0.21.0
 	google.golang.org/grpc v1.69.2
 	google.golang.org/protobuf v1.36.1
diff --git a/go.sum b/go.sum
index 94bd1fd34..26415b5cb 100644
--- a/go.sum
+++ b/go.sum
@@ -1081,8 +1081,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
-golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
+golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/go.work.sum b/go.work.sum
index 2fc3fa06b..d77edb1dc 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -1263,6 +1263,8 @@ golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2
 golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
 golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
 golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
+golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
diff --git a/internal/modules/tests_grpc.go b/internal/modules/tests_grpc.go
index 5a2428305..85f0fc091 100644
--- a/internal/modules/tests_grpc.go
+++ b/internal/modules/tests_grpc.go
@@ -58,6 +58,10 @@ func TestGRPCServer(ctx context.Context) (*grpc.ClientConn, func(p GRPCServerPar
 		)
 
 		for _, service := range p.Services {
+			if service == nil {
+				continue
+			}
+
 			service.RegisterServer(srv)
 		}
 
diff --git a/internal/tests/certs/gen_cert.sh b/internal/tests/certs/gen_cert.sh
index 8d598aaa5..88a6c06a7 100755
--- a/internal/tests/certs/gen_cert.sh
+++ b/internal/tests/certs/gen_cert.sh
@@ -1,4 +1,5 @@
-#!/bin/bash
+#!/usr/bin/env bash
+
 # Regenerate the self-signed certificate for local host. Recent versions of firefox and chrome(ium)
 # require a certificate authority to be imported by the browser (localhostCA.pem) while
 # the server uses a cert and key signed by that certificate authority.
@@ -6,13 +7,13 @@
 CA_PASSWORD=notsafe
 
 # Generate the root certificate authority key with the set password
-openssl genrsa -des3 -passout pass:$CA_PASSWORD -out localhostCA.key 2048
+openssl genrsa -des3 -passout pass:$CA_PASSWORD -out localhostCA.key 4096
 
 # Generate a root-certificate based on the root-key for importing to browsers.
 openssl req -x509 -new -nodes -key localhostCA.key -passin pass:$CA_PASSWORD -config localhostCA.conf -sha256 -days 1825 -out localhostCA.pem
 
 # Generate a new private key
-openssl genrsa -out localhost.key 2048
+openssl genrsa -out localhost.key 4096
 
 # Generate a Certificate Signing Request (CSR) based on that private key (reusing the
 # localhostCA.conf details)
diff --git a/internal/tests/certs/localhost.crt b/internal/tests/certs/localhost.crt
index be35c52fc..0918483f4 100644
--- a/internal/tests/certs/localhost.crt
+++ b/internal/tests/certs/localhost.crt
@@ -1,30 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIFODCCBCCgAwIBAgIJAMmbhUg0bRR9MA0GCSqGSIb3DQEBCwUAMIHDMQswCQYD
-VQQGEwJVUzETMBEGA1UECAwKR1JQQyBTdGF0ZTESMBAGA1UEBwwJR1JQQyBUb3du
-MSgwJgYDVQQKDB9HUlBDIFdlYiBsb2NhbGhvc3QgT3JnYW5pc2F0aW9uMRYwFAYD
-VQQLDA1PcmcgVW5pdCBOYW1lMSQwIgYDVQQDDBtHUlBDIFdlYiBleGFtcGxlIGRl
-diBzZXJ2ZXIxIzAhBgkqhkiG9w0BCQEWFGdycGMtd2ViQGV4YW1wbGUuY29tMB4X
-DTIxMTAyNzE5NDgyMFoXDTI0MDgxNjE5NDgyMFowgcMxCzAJBgNVBAYTAlVTMRMw
-EQYDVQQIDApHUlBDIFN0YXRlMRIwEAYDVQQHDAlHUlBDIFRvd24xKDAmBgNVBAoM
-H0dSUEMgV2ViIGxvY2FsaG9zdCBPcmdhbmlzYXRpb24xFjAUBgNVBAsMDU9yZyBV
-bml0IE5hbWUxJDAiBgNVBAMMG0dSUEMgV2ViIGV4YW1wbGUgZGV2IHNlcnZlcjEj
-MCEGCSqGSIb3DQEJARYUZ3JwYy13ZWJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQC66Y3vZznzPL9bscrvRch7dzzD538XlnYlcfLp
-rYYmOeWW1vM+/+KTqgb4GuKqZq6rGnhNEoQhRH0i4kZa7VgvY+mvFqGPrnjPOkYQ
-S2GoemwKIUqPapJtB8pM6o7hdycKYNn3QvdORmKduWOYzPLriHkHEAEH1zK9UvkO
-kGM9T2U0xMBATk9V/M/V18psKG90tndit+3+vN384yVR5KL0i9wQBAQWYa/IMF6V
-Q8n2hoJbED2pdYkQFeymTBMIqr7g7MkK0im6ZqW2MDIrn6rkjyd8odlXuaRLAPGp
-mV7Ii5JK2eyK+rH2QCb7slGl6nHpadYD4PEvd3ajlyzJdH3/AgMBAAGjggErMIIB
-JzCB4gYDVR0jBIHaMIHXoYHJpIHGMIHDMQswCQYDVQQGEwJVUzETMBEGA1UECAwK
-R1JQQyBTdGF0ZTESMBAGA1UEBwwJR1JQQyBUb3duMSgwJgYDVQQKDB9HUlBDIFdl
-YiBsb2NhbGhvc3QgT3JnYW5pc2F0aW9uMRYwFAYDVQQLDA1PcmcgVW5pdCBOYW1l
-MSQwIgYDVQQDDBtHUlBDIFdlYiBleGFtcGxlIGRldiBzZXJ2ZXIxIzAhBgkqhkiG
-9w0BCQEWFGdycGMtd2ViQGV4YW1wbGUuY29tggkA/2+s4xt7kvEwCQYDVR0TBAIw
-ADALBgNVHQ8EBAMCBPAwKAYDVR0RBCEwH4IJbG9jYWxob3N0ggh0ZXN0aG9zdIII
-Y29yc2hvc3QwDQYJKoZIhvcNAQELBQADggEBADWb8cis27F7benX5KJWwNX4C9Fb
-YDCsOWGNW3U2Q/gcdNkBl5ovu9nfskRGRDFk0x+2tQEaE1PEwCDWrhTnAqbTwdBn
-ZRslmzVBdDTD4p/R4DEJIk1/tWiiTZnF7/ZJypvBkqLHnYMi7Dpi6587G4iruCUN
-1gD46j1Eh0wsMNJY0J9uaXtkgRg5yR7fCPw4E1tmC0tqlW9zKGuF2moN1p4cPjvL
-ZUg3/0y/xq0ckM14PnyQ1HLrt3cxEUI649L2iVaE9nasXnb3bU4YJFvFwjpeP+Rc
-9xT0ZhTp8m3juU3wjfWjpJntEQn96xocRFioEaMxpCnHMZ5q6TWDHNTg9hw=
+MIIGnDCCBISgAwIBAgIUVXg8qyE8yYt6vTJAr384zy5j6kQwDQYJKoZIhvcNAQEL
+BQAwgcMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApHUlBDIFN0YXRlMRIwEAYDVQQH
+DAlHUlBDIFRvd24xKDAmBgNVBAoMH0dSUEMgV2ViIGxvY2FsaG9zdCBPcmdhbmlz
+YXRpb24xFjAUBgNVBAsMDU9yZyBVbml0IE5hbWUxJDAiBgNVBAMMG0dSUEMgV2Vi
+IGV4YW1wbGUgZGV2IHNlcnZlcjEjMCEGCSqGSIb3DQEJARYUZ3JwYy13ZWJAZXhh
+bXBsZS5jb20wHhcNMjUwMTA1MTcyMzM0WhcNMjcxMDI2MTcyMzM0WjCBwzELMAkG
+A1UEBhMCVVMxEzARBgNVBAgMCkdSUEMgU3RhdGUxEjAQBgNVBAcMCUdSUEMgVG93
+bjEoMCYGA1UECgwfR1JQQyBXZWIgbG9jYWxob3N0IE9yZ2FuaXNhdGlvbjEWMBQG
+A1UECwwNT3JnIFVuaXQgTmFtZTEkMCIGA1UEAwwbR1JQQyBXZWIgZXhhbXBsZSBk
+ZXYgc2VydmVyMSMwIQYJKoZIhvcNAQkBFhRncnBjLXdlYkBleGFtcGxlLmNvbTCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMXVw8ESiIHzCTe8maVb4ySd
+Q5A/3qprW7W2fiiGqk6xydaDUgOvGf0ETTp96+QwEx6O12xkiCINwcoQROs+9lFg
+W5yT6ULDFHEOrGY5qnoJQQttz4E5rbXlt8u9TcpxyFyfuhfCsF00vozAmtjlhBzi
+0eIDyamtw6z8pIXorgvX+1+XzcI1fftR0CP4rhk8p3BLm10iUoauA1qlYa3wmPw3
+NEqxKd7YpnGd39xHi7ivyYdPrFLZdWGaEYkho+IYfB7YoBmyiPvPSnHTmommpBC6
+RmiTQZyF8tv4QICA3uPm58vgvHIdHCe3dBX/M2zbFk1Hr1hQQ5YWxH9e7whQhUHP
+DwdDcMRsckPNdoptViq7NDNw4fYLjAGXu+01UHIo6VDSP7WHZrTr1Xq7a84UihBq
+jdYM6mQD2k/fIc/M1C4UUoPnqwjuaN5Svk5aV6H0hqOT4TVgm2Z02sRE152/kj/z
+Ydn8Bv3rAAbkNfLtu3dacWAJKxQhvUtB7kwhJw1XO7Q+ZZGcySo/MOdCN1B1K+5c
+cTxtvg0Af5ypb7BsDkomvFUc8a+xrCM057dT3Du0BUN7I3+u/D14SX0+RJFfPIbP
+q39NOXQ1KAKELuyPpX5G+qWXq2sO1EhJIYr+gfo+XhqzvOhj101TiBtcv34xqRtl
+VSyoyBJ3+NLKgr+Q6G5FAgMBAAGjgYUwgYIwHwYDVR0jBBgwFoAUahuSMP6KzcQG
+K22yJoVhCGpjXa8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwKAYDVR0RBCEwH4IJ
+bG9jYWxob3N0ggh0ZXN0aG9zdIIIY29yc2hvc3QwHQYDVR0OBBYEFNkuh8nMoiOy
+rwb7dieRQU0jqpOzMA0GCSqGSIb3DQEBCwUAA4ICAQAbdCusmSQUMACCPAVfgbAx
+lWtCKAFIep/Hd4Ep7/vhXceq8OiHBRf2XNQQM4nm2mzeCKvyIrlOkUUAtWHyP8kC
+TlBRg/dg1hd7bHtDly2Y0fpVEjg+sJ5UliLv3OkR1FDGM6p5PFYnXi9xYNbgw4sD
+sJ2kGL+PSlTvFBFZJlWS7YvjrvGOEOqwuPGlb98NzpuCXg5gSPEWr+NgUTAlpdVB
+ESE2zCcxVmA/wmK82rLrxbZ+OdwWTzh4lqfeA/2b7ZDLhg6YSCTalMj+eRHMBV2Q
+kDA3gBAaLJKtZrF9HJDAI58RQV2//g75ULYOk0WQ/VKJpld2O8Esz4OSnH9ktaO+
+3RoG9f6nduAjjoqH7OX+Wrsj9gpP/0AWwU90ik7QV2JdStfl6x2xUxvlkfHCUKnQ
+z2ZQFWss5gibrrkZGz5HzDSukjAG1Jc47cCx+ekzA9B/knceFlfgaRBXvEuyyKE/
+QqUS2M/3HlZSo1JoqjVzGpMHZTIRVFEQvx2o/U8weeh314Oar1f1i0emQY4warI1
+0Uyuhz+JrjGjSAf36NRtVmV9Gh2hiMsV7ZUA6H3yz0OAaB8iSzXWtbhXVP8myU2B
+4EPt71hHnNkCekD44gfwJqx06v1TNnReUgSypzF3ToDqA7E75wl5j/qSUG6LAykG
+mooVGS4HLh9jmjPvO6A8oA==
 -----END CERTIFICATE-----
diff --git a/internal/tests/certs/localhost.key b/internal/tests/certs/localhost.key
index 146ee0e99..bb618a16d 100644
--- a/internal/tests/certs/localhost.key
+++ b/internal/tests/certs/localhost.key
@@ -1,27 +1,52 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAuumN72c58zy/W7HK70XIe3c8w+d/F5Z2JXHy6a2GJjnlltbz
-Pv/ik6oG+Briqmauqxp4TRKEIUR9IuJGWu1YL2Pprxahj654zzpGEEthqHpsCiFK
-j2qSbQfKTOqO4XcnCmDZ90L3TkZinbljmMzy64h5BxABB9cyvVL5DpBjPU9lNMTA
-QE5PVfzP1dfKbChvdLZ3Yrft/rzd/OMlUeSi9IvcEAQEFmGvyDBelUPJ9oaCWxA9
-qXWJEBXspkwTCKq+4OzJCtIpumaltjAyK5+q5I8nfKHZV7mkSwDxqZleyIuSStns
-ivqx9kAm+7JRpepx6WnWA+DxL3d2o5csyXR9/wIDAQABAoIBAQCao5JfaGsEd9Tl
-+xGnpnd41qy6c/OtQzmaP0020e6z/6CYjFwRWklN3BUJ/cxcKLoIK80uDsysbWqO
-iuCkZ8tW4fW7eyDNrA6dfFvtLUCt0CNEukhioUxl0lUoD8OIfDkbmAedT5Ul+Ius
-bG4fRCkSfwWKt03y+7Mp+dS+nOzOElDANlxxZRUjBHx08VPE4/r9L4efFCU3T4Jd
-I72IzZeEXXH2R4R4POzBoPFP+LHg1N+JUUtAkArd30Ar3oc4EReWqSqPqMOiMPmU
-mwFgP3eAIMP+FPyM5KELMpzz6HHVwm9Kh7DMAwDaEb3IR84uulqsqrg48mKmi2Sr
-DmAK0YGZAoGBAOJry2CdxFmj45Ca2eNq1cix+1xhQo0VvIiUeBiJmNUHSX5gQDhQ
-9Kd5X4TR6/DqTK+oHRVDtDs/zxeqP5CSsNpmbz2FBrkjka7SYpZVv3/liczAT3Hy
-H67Pvw0yIucmw1Cv7+rsix2YsmGd0EA/6XJik44SJ2lfMpQrFqJiBNMbAoGBANNU
-d8bpkMBZEZFWreFiuhWGO5+W9WX+M6b6DMAmtuTjIv7NMiVpxs9r7ymUO5mt2vfQ
-LRxK3X+MpYPcUBsRhF5bu0WTXgKW/VL84WyzSYvlT8EENKCtfSYsnUZYCjOiFUk0
-769E8nGYuXpTDKOIg9Jv45r7PErGgBEOCK/eGgrtAoGBAMfG9raz3Yh+S47Oosu+
-+wxOxgtXoaHcePJFlcWIurnT6SvBf0hxXbzbIcWOd1ClWq5udeLKTx8sCOzHgbht
-RfAeC67LTghS8vq+lNAyrnoJrNFlKXPPf9b9ZIQfJZ6wnAr4gYbV2VVu4o2w8guO
-mMsdYTYsnGuj3HvRnPH/7GPbAoGAFZawccKUhgHTWJyZQMgcKGzBFImQYi34ytsK
-iGqsDm/huFPwBoBqze/By+aXvBhVoTFEGnrPa+NLWVAdYtaERjtqwy3N0cfo8xxg
-TwF1xvPTFO3ADpYKjebK3k/KIwIw2Hyu66HIfrBSalunk+EzTkEd6Ew4GY9zr8pW
-OtkeofUCgYEAta0CrWkWcBi5SUcMpD9SkTy10ejYb7/BnG+VYr9l/jBO8DCeFuj9
-OGMvRaQLWcs9PG7286VkLBMUo2pc+mpTbw6WR3qrDojoiE7P3DUnAzMQTsZe69lD
-vXp5yhu9c9O5QpK6uzJ64rVCYE6g+noUe/dJNoMUndPF1RahW5nELTo=
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+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
+6bT/jp3T9snRUPOEMX/ERUTUyUNiAC/X
+-----END PRIVATE KEY-----
diff --git a/internal/tests/certs/localhostCA.conf b/internal/tests/certs/localhostCA.conf
index 70edc20df..0b18d9dce 100644
--- a/internal/tests/certs/localhostCA.conf
+++ b/internal/tests/certs/localhostCA.conf
@@ -20,4 +20,4 @@ subjectAltName = @alt_names
 [ alt_names ]
 DNS.1 = localhost
 DNS.2 = testhost
-DNS.3 = corshost
\ No newline at end of file
+DNS.3 = corshost
diff --git a/internal/tests/certs/localhostCA.key b/internal/tests/certs/localhostCA.key
new file mode 100644
index 000000000..a35331463
--- /dev/null
+++ b/internal/tests/certs/localhostCA.key
@@ -0,0 +1,54 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+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
+/Nmqd7m+Y2MEkZlHEVv6uIG7P3ReR/ly
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/internal/tests/certs/localhostCA.pem b/internal/tests/certs/localhostCA.pem
index a0dbe9e09..313830989 100644
--- a/internal/tests/certs/localhostCA.pem
+++ b/internal/tests/certs/localhostCA.pem
@@ -1,26 +1,37 @@
 -----BEGIN CERTIFICATE-----
-MIIEXDCCA0SgAwIBAgIJAP9vrOMbe5LxMA0GCSqGSIb3DQEBCwUAMIHDMQswCQYD
-VQQGEwJVUzETMBEGA1UECAwKR1JQQyBTdGF0ZTESMBAGA1UEBwwJR1JQQyBUb3du
-MSgwJgYDVQQKDB9HUlBDIFdlYiBsb2NhbGhvc3QgT3JnYW5pc2F0aW9uMRYwFAYD
-VQQLDA1PcmcgVW5pdCBOYW1lMSQwIgYDVQQDDBtHUlBDIFdlYiBleGFtcGxlIGRl
-diBzZXJ2ZXIxIzAhBgkqhkiG9w0BCQEWFGdycGMtd2ViQGV4YW1wbGUuY29tMB4X
-DTIxMTAyNzE5NDgyMFoXDTI2MTAyNjE5NDgyMFowgcMxCzAJBgNVBAYTAlVTMRMw
-EQYDVQQIDApHUlBDIFN0YXRlMRIwEAYDVQQHDAlHUlBDIFRvd24xKDAmBgNVBAoM
-H0dSUEMgV2ViIGxvY2FsaG9zdCBPcmdhbmlzYXRpb24xFjAUBgNVBAsMDU9yZyBV
-bml0IE5hbWUxJDAiBgNVBAMMG0dSUEMgV2ViIGV4YW1wbGUgZGV2IHNlcnZlcjEj
-MCEGCSqGSIb3DQEJARYUZ3JwYy13ZWJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCvifPlvbJS0c5YlzwG7RbIfOoJICk+/jY8tt+B
-3FLE27i5Rl8/ftYpe3wR443K4V4SJ0iCiCfI3SxmGOJeNAtac0sD7DTlE7c/UXOy
-c/WQuP0/nShNikJkBNngTHZmWtGmXg/q3FyHhDqLR0KMEaiv/eyUBNteNJHbtOwm
-Nc33JUE1udUk0tjkI/Z/L2n0oUUuYN6tAMwmMisT4Qv88Ybk2XpjJEPoqnvBzF2n
-llYgbcgHzefFJZtJygMT9D0ORKMwqpiAzxGd5iJHAcn+VQTOb9GQhPmyeDNj6Kmj
-M0TVTIBjzvy9Ww11Y9HvVgvYhUEbMjzJSw5bA4BvmSqhxC+7AgMBAAGjUTBPMA4G
-A1UdDwEB/wQEAwIDiDATBgNVHSUEDDAKBggrBgEFBQcDATAoBgNVHREEITAfggls
-b2NhbGhvc3SCCHRlc3Rob3N0gghjb3JzaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEA
-myWvrpQppFWeg2E0PZGo6dR+DAFgkXtCotEhlSOWsU4MfV+IjrxwvbICkQ6nFSF8
-9FFBiXKbhKxGEEWCqlqtXCPCxotypUavqOfeFNHmOHNQW4C3JbYGbHBunqbH4qOY
-f2rHvjT0GjPvKcgy0e750amAgoRQWnTNrHZ9ScddvZhwxdRAQrO4OM36D0YRl6yF
-MU5Fz1KmHlfp1vPLbUcrXZDil9azis9Iqpxhy4TcUoQJwyeyuGhxzAXW9IqOjBng
-aIb1dsOYVGzjn8EWa6v7ZyUYQQ7kRIv8naksLhBarK3mW90Oyxu/4TXi/75EE92k
-3NqYlMOu5fZkhLmfGIUhug==
+MIIGhjCCBG6gAwIBAgIUN3UQg3aSVlu4vaCCTILntcfQOH0wDQYJKoZIhvcNAQEL
+BQAwgcMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApHUlBDIFN0YXRlMRIwEAYDVQQH
+DAlHUlBDIFRvd24xKDAmBgNVBAoMH0dSUEMgV2ViIGxvY2FsaG9zdCBPcmdhbmlz
+YXRpb24xFjAUBgNVBAsMDU9yZyBVbml0IE5hbWUxJDAiBgNVBAMMG0dSUEMgV2Vi
+IGV4YW1wbGUgZGV2IHNlcnZlcjEjMCEGCSqGSIb3DQEJARYUZ3JwYy13ZWJAZXhh
+bXBsZS5jb20wHhcNMjUwMTA1MTcyMzM0WhcNMzAwMTA0MTcyMzM0WjCBwzELMAkG
+A1UEBhMCVVMxEzARBgNVBAgMCkdSUEMgU3RhdGUxEjAQBgNVBAcMCUdSUEMgVG93
+bjEoMCYGA1UECgwfR1JQQyBXZWIgbG9jYWxob3N0IE9yZ2FuaXNhdGlvbjEWMBQG
+A1UECwwNT3JnIFVuaXQgTmFtZTEkMCIGA1UEAwwbR1JQQyBXZWIgZXhhbXBsZSBk
+ZXYgc2VydmVyMSMwIQYJKoZIhvcNAQkBFhRncnBjLXdlYkBleGFtcGxlLmNvbTCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfB2DKGUhHbowqpi8zlYKE6
+d+cOd7tGLG5/y8qFZ0uWTBpE7LMMACGA/2tWTKdhq/VGepHaOFbCIJMyatrT9U3K
+9pkegEuzugWih4Ldh2CKdzTWFQ2LhKl2qeD3E51NTOwzlHTNImtAQklgDht8ZCpJ
+Aabdr5t0bMwJYhfUy6vAyUiZyNDbKXN+77Q23cWg+ogNHlCcS7N/7jcjItThCGrT
+MfxUU4WSmzZT+wloJDz6NmSolMWY2B+kGwx0uiFznrh1ls9JxSO1+dMvipW2KQvM
+kJ8eTvZezcBAMcWYMtrPjG6hzbfifyJyU4JevzzmrRWQI8yfCRbua0FlTMrLudyS
+rzQS7xQ+NhwoZxTRHoY87XU1oBfydW556+2AYkdZ6wMpzZZtdXY24UURCA4AnaPz
+GIZEBpeJG27yc0HCgfYm47p90e4pOHdo+BMFyPcyIhUGpmCVOQfJY4ihPwniAU8R
+AaFQP1mBLXvFx0A7ygl1A5RkTLV5VNKpjVMkxwzgm22VIg+ZjB4kkLX4P5aGcxvf
+dW1Al/UY5kcrLe+LEHs9cCqGzNTuUfFEl8UtasaaT7SHzlysERIEtKqrprk1LFri
+0jexzwIOK82ePokOZp2snAabdBgAJnZeCRWlMXuF7fz0uBZZ2b0+NuQzJap6Dcng
+9Y2Xe0RYmIEa03dob/spAgMBAAGjcDBuMA4GA1UdDwEB/wQEAwIDiDATBgNVHSUE
+DDAKBggrBgEFBQcDATAoBgNVHREEITAfgglsb2NhbGhvc3SCCHRlc3Rob3N0gghj
+b3JzaG9zdDAdBgNVHQ4EFgQUahuSMP6KzcQGK22yJoVhCGpjXa8wDQYJKoZIhvcN
+AQELBQADggIBANMtB1STiqf2Ejq9LXOyVbETEoV9aWDLUYu1WhJyuPkLo+MIJE+d
+dw8pj2TXkQFobt+yM33V5G+EZLgFBQaOvQ7K/lSmp7koLHeqTV9/xs3u2zwoQTRJ
+Y0cFy3KYK8IL75aqqFND+v67rwwO28nVYdTiaM0WNtkYU10KrpcDYR+QRBakXzpI
+D9U+HJ0hUJEPpJOSqTowsA6nKoFKgI8uCTXcWSP9svIBHbhcQg7qs98cDzw3/Eye
+YZwYuf/Zg97q+YQDEfnksegghfhGyOgc0c3cYjmOYdKNu3FKhm/baBHKYrgY1Eig
+V0C0jA1qgCnZsO03IV/NDyeMF3JO35S9eQ+Gt4wR2Xv2mCUFGdhnepqCfablAzAP
+jpdxfCy+vrC2kAsm1pTv3UFo+ZGwUoHUrJEOcjNRMyqTIUQygtjG37cvy7Xeaj7s
+/x7nbD15Dpxz9uOLqsE+J1sHgFz00AuqZvmxBKdgl7b2EYohmOs6OG0jbfbikKBf
+vXJcnHCM+ufZ4aF2ZMsqLcUf02w5vhCYpXc3x9I6+Hq68JMjMg+RTAPmW+brwAti
+YtTprdzlZtA4xqRNNRVpuzuvMeZXQF2D73NWM/RBq7nyCUahtu7ES/DZ4VcsQVPo
+ZVRpkUxMB4TgPjaAOYbRAFwY/IkHI2HODTUNSXvnN6smC82aTbU9ll0L
 -----END CERTIFICATE-----
diff --git a/internal/tests/certs/localhostCA.srl b/internal/tests/certs/localhostCA.srl
new file mode 100644
index 000000000..ed01e978c
--- /dev/null
+++ b/internal/tests/certs/localhostCA.srl
@@ -0,0 +1 @@
+55783CAB213CC98B7ABD3240AF7F38CF2E63EA44
diff --git a/package.json b/package.json
index a19407973..5b3e77b8b 100644
--- a/package.json
+++ b/package.json
@@ -45,11 +45,11 @@
         "leaflet-contextmenu": "1.4.0",
         "maska": "3.0.4",
         "mdi-vue3": "7.4.47",
-        "nuxt-zod-i18n": "1.11.2",
+        "nuxt-zod-i18n": "1.11.4",
         "pinia": "2.3.0",
         "slugify": "1.6.6",
         "splitpanes": "3.1.5",
-        "uuid": "11.0.3",
+        "uuid": "11.0.4",
         "v-calendar": "3.1.2",
         "v-code-diff": "1.13.1",
         "vue-countup-v3": "1.4.2",
@@ -103,7 +103,7 @@
         "eslint-plugin-prettier": "5.2.1",
         "eslint-plugin-vue": "9.32.0",
         "nuxi": "3.17.2",
-        "nuxt": "3.14.1592",
+        "nuxt": "3.15.1",
         "nuxt-tiptap-editor": "2.1.4",
         "nuxt-typed-router": "3.7.2",
         "pinia-plugin-persistedstate": "4.2.0",
@@ -117,7 +117,7 @@
         "prettier-plugin-tailwindcss": "0.6.9",
         "protoc": "1.1.3",
         "protoc-gen-js": "3.21.4",
-        "sass": "1.83.0",
+        "sass": "1.83.1",
         "tailwindcss": "3.4.17",
         "tiptap-extension-auto-joiner": "0.1.3",
         "tiptap-extension-font-size": "^1.2.0",
@@ -128,7 +128,8 @@
         "vue-tsc": "2.2.0"
     },
     "resolutions": {
-        "@nuxt/ui": "2.19.1"
+        "@nuxt/ui": "2.19.1",
+        "@nuxt/kit": "3.15.1"
     },
     "packageManager": "pnpm@9.15.2"
 }
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 94cf34657..f927e3593 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -29,6 +29,8 @@ type Config struct {
 	Discord Discord `yaml:"discord"`
 
 	Game Game `yaml:"game"`
+
+	Sync Sync `yaml:"sync"`
 }
 
 type TracingExporter string
@@ -178,8 +180,6 @@ type OAuth2Mapping struct {
 type Auth struct {
 	SuperuserGroups []string `yaml:"superuserGroups"`
 	SuperuserUsers  []string `yaml:"superuserUsers"`
-
-	SyncAPITokens []string `yaml:"syncAPITokens"`
 }
 
 type DispatchCenter struct {
@@ -231,3 +231,8 @@ type Game struct {
 	StartJobGrade int32  `default:"0" yaml:"startJobGrade"`
 	DefaultLocale string `default:"en" yaml:"defaultLocale"`
 }
+
+type Sync struct {
+	Enabled   bool     `yaml:"enabled"`
+	APITokens []string `yaml:"apiTokens"`
+}
diff --git a/pkg/dbsync/client_auth.go b/pkg/dbsync/client_auth.go
new file mode 100644
index 000000000..b8aa28e0d
--- /dev/null
+++ b/pkg/dbsync/client_auth.go
@@ -0,0 +1,18 @@
+package dbsync
+
+import "context"
+
+type tokenAuth struct {
+	token string
+}
+
+// Return value is mapped to request headers.
+func (t tokenAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) {
+	return map[string]string{
+		"authorization": "Bearer " + t.token,
+	}, nil
+}
+
+func (tokenAuth) RequireTransportSecurity() bool {
+	return false
+}
diff --git a/pkg/dbsync/sync.go b/pkg/dbsync/sync.go
index a9b1ee0cc..1c59c982a 100644
--- a/pkg/dbsync/sync.go
+++ b/pkg/dbsync/sync.go
@@ -9,12 +9,15 @@ import (
 	"sync"
 
 	"github.com/XSAM/otelsql"
+	pbsync "github.com/fivenet-app/fivenet/gen/go/proto/services/sync"
 	"github.com/fivenet-app/fivenet/pkg/config"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/collectors"
 	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
 	"go.uber.org/fx"
 	"go.uber.org/zap"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
 )
 
 var Module = fx.Module("dbsync",
@@ -31,6 +34,8 @@ type Sync struct {
 
 	cfg   *config.DBSync
 	state *DBSyncState
+
+	cli pbsync.SyncServiceClient
 }
 
 type Params struct {
@@ -89,6 +94,20 @@ func New(p Params) (*Sync, error) {
 	// Setup SQL Prometheus metrics collector
 	prometheus.MustRegister(collectors.NewDBStatsCollector(db, "fivenet"))
 
+	// Create GRPC client for sync if destination is given
+	if s.cfg.Destination.URL != "" {
+		cli, err := grpc.NewClient(s.cfg.Destination.URL,
+			grpc.WithTransportCredentials(insecure.NewCredentials()),
+			grpc.WithPerRPCCredentials(tokenAuth{
+				token: s.cfg.Destination.Token,
+			}),
+		)
+		if err != nil {
+			return nil, err
+		}
+		s.cli = pbsync.NewSyncServiceClient(cli)
+	}
+
 	ctx, cancel := context.WithCancel(context.Background())
 
 	p.LC.Append(fx.StartHook(func(_ context.Context) error {
@@ -111,6 +130,7 @@ func (s *Sync) Run(ctx context.Context) {
 		logger: s.logger,
 		db:     s.db,
 		cfg:    s.cfg,
+		cli:    s.cli,
 	}
 	if _, err := us.Sync(ctx); err != nil {
 		s.logger.Error("error during users sync", zap.Error(err))
diff --git a/pkg/dbsync/sync_jobs.go b/pkg/dbsync/sync_jobs.go
new file mode 100644
index 000000000..f3831f800
--- /dev/null
+++ b/pkg/dbsync/sync_jobs.go
@@ -0,0 +1,39 @@
+package dbsync
+
+import (
+	"context"
+	"database/sql"
+
+	pbsync "github.com/fivenet-app/fivenet/gen/go/proto/services/sync"
+	"github.com/fivenet-app/fivenet/pkg/config"
+	"go.uber.org/zap"
+)
+
+func init() {
+	syncerFactories["jobs"] = NewJobsSync
+}
+
+type jobsSync struct {
+	logger *zap.Logger
+	db     *sql.DB
+
+	cfg *config.DBSync
+
+	cli pbsync.SyncServiceClient
+}
+
+func NewJobsSync(logger *zap.Logger, db *sql.DB, cfg *config.DBSync, cli pbsync.SyncServiceClient) (ISyncer, error) {
+	return &jobsSync{
+		logger: logger,
+		db:     db,
+		cfg:    cfg,
+
+		cli: cli,
+	}, nil
+}
+
+func (s *jobsSync) Sync(ctx context.Context) (*TableSyncState, error) {
+	// TODO
+
+	return nil, nil
+}
diff --git a/pkg/dbsync/users.go b/pkg/dbsync/sync_users.go
similarity index 76%
rename from pkg/dbsync/users.go
rename to pkg/dbsync/sync_users.go
index 575086c50..7afe9b3e5 100644
--- a/pkg/dbsync/users.go
+++ b/pkg/dbsync/sync_users.go
@@ -6,6 +6,7 @@ import (
 	"strconv"
 
 	"github.com/fivenet-app/fivenet/gen/go/proto/resources/users"
+	pbsync "github.com/fivenet-app/fivenet/gen/go/proto/services/sync"
 	"github.com/fivenet-app/fivenet/pkg/config"
 	"github.com/go-jet/jet/v2/qrm"
 	"go.uber.org/zap"
@@ -20,13 +21,17 @@ type usersSync struct {
 	db     *sql.DB
 
 	cfg *config.DBSync
+
+	cli pbsync.SyncServiceClient
 }
 
-func NewUsersSync(logger *zap.Logger, db *sql.DB, cfg *config.DBSync) (ISyncer, error) {
+func NewUsersSync(logger *zap.Logger, db *sql.DB, cfg *config.DBSync, cli pbsync.SyncServiceClient) (ISyncer, error) {
 	return &usersSync{
 		logger: logger,
 		db:     db,
 		cfg:    cfg,
+
+		cli: cli,
 	}, nil
 }
 
@@ -50,6 +55,18 @@ func (s *usersSync) Sync(ctx context.Context) (*TableSyncState, error) {
 		return &TableSyncState{}, nil
 	}
 
+	if s.cli != nil {
+		if _, err := s.cli.SyncData(ctx, &pbsync.SyncDataRequest{
+			Data: &pbsync.SyncDataRequest_Users{
+				Users: &pbsync.DataUsers{
+					Users: users,
+				},
+			},
+		}); err != nil {
+			return nil, err
+		}
+	}
+
 	// If less users than limit are returned, we probably have reached the "end" of the table
 	// and need to reset the offset to 0
 	if len(users) < limit {
diff --git a/pkg/dbsync/types.go b/pkg/dbsync/types.go
index 59ef9c036..3bf900055 100644
--- a/pkg/dbsync/types.go
+++ b/pkg/dbsync/types.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"database/sql"
 
+	pbsync "github.com/fivenet-app/fivenet/gen/go/proto/services/sync"
 	"github.com/fivenet-app/fivenet/pkg/config"
 	"go.uber.org/zap"
 )
@@ -12,6 +13,6 @@ type ISyncer interface {
 	Sync(ctx context.Context) (*TableSyncState, error)
 }
 
-type SyncerFactory = func(logger *zap.Logger, db *sql.DB, cfg *config.DBSync) (ISyncer, error)
+type SyncerFactory = func(logger *zap.Logger, db *sql.DB, cfg *config.DBSync, cli pbsync.SyncServiceClient) (ISyncer, error)
 
 var syncerFactories = map[string]SyncerFactory{}
diff --git a/pkg/grpc/auth/client_token.go b/pkg/grpc/auth/client_token.go
new file mode 100644
index 000000000..73323490b
--- /dev/null
+++ b/pkg/grpc/auth/client_token.go
@@ -0,0 +1,24 @@
+package auth
+
+import "context"
+
+type ClientTokenAuth struct {
+	token string
+}
+
+func NewClientTokenAuth(token string) *ClientTokenAuth {
+	return &ClientTokenAuth{
+		token: token,
+	}
+}
+
+// Return value is mapped to request headers.
+func (t ClientTokenAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) {
+	return map[string]string{
+		"authorization": "Bearer " + t.token,
+	}, nil
+}
+
+func (ClientTokenAuth) RequireTransportSecurity() bool {
+	return true
+}
diff --git a/pkg/grpc/grpcws/README.md b/pkg/grpc/grpcws/README.md
index 96f78cbc9..c207a73ef 100644
--- a/pkg/grpc/grpcws/README.md
+++ b/pkg/grpc/grpcws/README.md
@@ -4,7 +4,7 @@ Based upon [GitHub improbable-eng/grpc-web](https://github.com/improbable-eng/gr
 
 ## Additional Modifications
 
-It has been adjusted to work with protobuf-ts in the context of this project.
+It has been adjusted to work with `protobuf-ts` in the context of this project.
 
 ## License
 
diff --git a/pkg/grpc/grpcws/client/client_test.go b/pkg/grpc/grpcws/client/client_test.go
new file mode 100644
index 000000000..28062cf8c
--- /dev/null
+++ b/pkg/grpc/grpcws/client/client_test.go
@@ -0,0 +1,144 @@
+package client
+
+import (
+	"context"
+	"net/http"
+	"sync/atomic"
+
+	"github.com/coder/websocket"
+	"github.com/fivenet-app/fivenet/gen/go/proto/resources/common/grpcws"
+	"google.golang.org/protobuf/proto"
+)
+
+type Client struct {
+	c *websocket.Conn
+
+	streamId atomic.Uint32
+}
+
+func New(ctx context.Context, url string, headers http.Header) (*Client, error) {
+	con, _, err := websocket.Dial(ctx, url, &websocket.DialOptions{
+		Subprotocols: []string{"grpc-websocket-channel"},
+		HTTPHeader:   headers,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	c := &Client{
+		c:        con,
+		streamId: atomic.Uint32{},
+	}
+	c.streamId.Store(0)
+
+	go c.read()
+
+	return c, nil
+}
+
+func (c *Client) read() {
+	for {
+		mType, r, err := c.c.Reader(context.TODO())
+		if err != nil {
+			return
+		}
+
+		if mType != websocket.MessageBinary {
+			continue
+		}
+
+		_ = r
+	}
+}
+
+func (c *Client) Close() error {
+	if c.c == nil {
+		return c.c.CloseNow()
+	}
+
+	return c.c.Close(websocket.StatusNormalClosure, "")
+}
+
+func (c *Client) getStreamId() uint32 {
+	return c.streamId.Add(1)
+}
+
+func (c *Client) NewChannel(headers map[string]*grpcws.HeaderValue) *WSChannel {
+	return &WSChannel{
+		c:        c.c,
+		streamId: c.getStreamId(),
+		headers:  headers,
+	}
+}
+
+type WSChannel struct {
+	c  *websocket.Conn
+	in chan grpcws.GrpcFrame
+
+	streamId uint32
+
+	headers map[string]*grpcws.HeaderValue
+}
+
+func (w *WSChannel) sendBody(ctx context.Context, msg proto.Message, complete bool) error {
+	out, err := proto.Marshal(msg)
+	if err != nil {
+		return err
+	}
+
+	body := &grpcws.GrpcFrame{
+		StreamId: w.streamId,
+		Payload: &grpcws.GrpcFrame_Body{
+			Body: &grpcws.Body{
+				Data:     w.wrapBodyData(out),
+				Complete: complete,
+			},
+		},
+	}
+
+	bodyOut, err := proto.Marshal(body)
+	if err != nil {
+		return err
+	}
+
+	if err := w.c.Write(ctx, websocket.MessageBinary, bodyOut); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (w *WSChannel) sendHeaders(ctx context.Context, operation string) error {
+	header := &grpcws.GrpcFrame{
+		StreamId: 1,
+		Payload: &grpcws.GrpcFrame_Header{
+			Header: &grpcws.Header{
+				Operation: operation,
+				Headers:   w.headers,
+			},
+		},
+	}
+
+	out, err := proto.Marshal(header)
+	if err != nil {
+		return err
+	}
+
+	if err := w.c.Write(ctx, websocket.MessageBinary, out); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (w *WSChannel) wrapBodyData(out []byte) []byte {
+	msgLen := len(out)
+	o := make([]byte, 5)
+	o[0] = 0
+	o[1] = byte(msgLen >> 24)
+	o[2] = byte(msgLen >> 16)
+	o[3] = byte(msgLen >> 8)
+	o[4] = byte(msgLen)
+
+	return append(o, out...)
+}
diff --git a/pkg/grpc/grpcws/websocket_channel.go b/pkg/grpc/grpcws/websocket_channel.go
index bbdd92778..46ba3e7c1 100644
--- a/pkg/grpc/grpcws/websocket_channel.go
+++ b/pkg/grpc/grpcws/websocket_channel.go
@@ -110,7 +110,6 @@ func (stream *GrpcStream) close() {
 func (stream *GrpcStream) Read(p []byte) (int, error) {
 	// grpclog.Infof("reading from channel %v", stream.id)
 	if stream.remainingBuffer != nil {
-
 		// If the remaining buffer fits completely inside the argument slice then read all of it and return any error
 		// that was retained from the original call
 		if len(stream.remainingBuffer) <= len(p) {
diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go
index 926ab4dfa..1f62e40c0 100644
--- a/pkg/grpc/server.go
+++ b/pkg/grpc/server.go
@@ -142,6 +142,10 @@ func NewServer(p ServerParams) (ServerResult, error) {
 	grpclog.SetLoggerV2(zapgrpc.NewLogger(p.Logger))
 
 	for _, service := range p.Services {
+		if service == nil {
+			continue
+		}
+
 		service.RegisterServer(srv)
 	}
 
diff --git a/pkg/server/http.go b/pkg/server/http.go
index 816991944..192069dfe 100644
--- a/pkg/server/http.go
+++ b/pkg/server/http.go
@@ -25,6 +25,8 @@ import (
 	"go.uber.org/fx"
 	"go.uber.org/zap"
 	"go.uber.org/zap/zapcore"
+	"golang.org/x/net/http2"
+	"golang.org/x/net/http2/h2c"
 	"google.golang.org/grpc"
 )
 
@@ -42,9 +44,10 @@ type Params struct {
 
 	LC fx.Lifecycle
 
-	Logger *zap.Logger
-	Config *config.Config
-	Engine *gin.Engine
+	Logger  *zap.Logger
+	Config  *config.Config
+	Engine  *gin.Engine
+	GRPCSrv *grpc.Server
 }
 
 type Result struct {
@@ -54,16 +57,37 @@ type Result struct {
 }
 
 func wrapLogger(log *zap.Logger) *zap.Logger {
-	return log.Named("http_server")
+	return log.Named("http")
+}
+
+type handler struct {
+	gin  http.Handler
+	grpc *grpc.Server
+}
+
+func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	if r.ProtoMajor == 2 && strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
+		h.grpc.ServeHTTP(w, r)
+		return
+	}
+
+	h.gin.ServeHTTP(w, r)
 }
 
 // New builds an HTTP server that will begin serving requests
 // when the Fx application starts.
 func New(p Params) (Result, error) {
-	// Create HTTP Server for graceful shutdown handling
+	// Create HTTP Server for graceful shutdown handling and h2c wrapped handler
 	srv := &http.Server{
-		Addr:    p.Config.HTTP.Listen,
-		Handler: p.Engine,
+		Addr: p.Config.HTTP.Listen,
+		Handler: h2c.NewHandler(
+			&handler{
+				gin:  p.Engine,
+				grpc: p.GRPCSrv,
+			},
+			&http2.Server{},
+		),
+		ErrorLog: zap.NewStdLog(p.Logger),
 	}
 
 	p.LC.Append(fx.Hook{
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f11dea238..4b86ea670 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,6 +6,7 @@ settings:
 
 overrides:
   '@nuxt/ui': 2.19.1
+  '@nuxt/kit': 3.15.1
 
 importers:
 
@@ -25,16 +26,16 @@ importers:
         version: 1.2.18
       '@nuxt/content':
         specifier: 2.13.4
-        version: 2.13.4(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
+        version: 2.13.4(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
       '@nuxt/fonts':
         specifier: 0.10.3
-        version: 0.10.3(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+        version: 0.10.3(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       '@nuxt/ui-pro':
         specifier: 1.6.0
-        version: 1.6.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+        version: 1.6.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       '@nuxtjs/robots':
         specifier: 5.1.0
-        version: 5.1.0(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+        version: 5.1.0(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       '@pinia/nuxt':
         specifier: 0.9.0
         version: 0.9.0(magicast@0.3.5)(pinia@2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)))(rollup@4.29.1)
@@ -87,8 +88,8 @@ importers:
         specifier: 7.4.47
         version: 7.4.47(vue@3.5.13(typescript@5.7.2))
       nuxt-zod-i18n:
-        specifier: 1.11.2
-        version: 1.11.2(magicast@0.3.5)(rollup@4.29.1)
+        specifier: 1.11.4
+        version: 1.11.4(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)
       pinia:
         specifier: 2.3.0
         version: 2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))
@@ -99,8 +100,8 @@ importers:
         specifier: 3.1.5
         version: 3.1.5
       uuid:
-        specifier: 11.0.3
-        version: 11.0.3
+        specifier: 11.0.4
+        version: 11.0.4
       v-calendar:
         specifier: 3.1.2
         version: 3.1.2(@popperjs/core@2.11.8)(vue@3.5.13(typescript@5.7.2))
@@ -125,10 +126,10 @@ importers:
     devDependencies:
       '@nuxt/devtools':
         specifier: 1.7.0
-        version: 1.7.0(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+        version: 1.7.0(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       '@nuxt/eslint':
         specifier: 0.7.4
-        version: 0.7.4(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+        version: 0.7.4(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       '@nuxtjs/fontaine':
         specifier: 0.4.4
         version: 0.4.4(magicast@0.3.5)(rollup@4.29.1)
@@ -230,7 +231,7 @@ importers:
         version: 12.3.0(typescript@5.7.2)
       '@vueuse/nuxt':
         specifier: 12.3.0
-        version: 12.3.0(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(typescript@5.7.2)
+        version: 12.3.0(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(typescript@5.7.2)
       '@vueuse/router':
         specifier: 12.3.0
         version: 12.3.0(typescript@5.7.2)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.2)))
@@ -256,8 +257,8 @@ importers:
         specifier: 3.17.2
         version: 3.17.2
       nuxt:
-        specifier: 3.14.1592
-        version: 3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2))
+        specifier: 3.15.1
+        version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1)
       nuxt-tiptap-editor:
         specifier: 2.1.4
         version: 2.1.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/extension-code-block@2.10.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/pm@2.10.4))(highlight.js@11.11.0)(magicast@0.3.5)(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
@@ -298,8 +299,8 @@ importers:
         specifier: 3.21.4
         version: 3.21.4
       sass:
-        specifier: 1.83.0
-        version: 1.83.0
+        specifier: 1.83.1
+        version: 1.83.1
       tailwindcss:
         specifier: 3.4.17
         version: 3.4.17
@@ -1272,22 +1273,18 @@ packages:
   '@nuxt/icon@1.10.3':
     resolution: {integrity: sha512-ESIiSIpETLLcn5p4U8S0F3AQ5Mox0MoHAVKczamY4STh3Dwrc8labLhtN6lunwpQEv6UGuiutdvfkJ88zu44Ew==}
 
-  '@nuxt/kit@3.14.1592':
-    resolution: {integrity: sha512-r9r8bISBBisvfcNgNL3dSIQHSBe0v5YkX5zwNblIC2T0CIEgxEVoM5rq9O5wqgb5OEydsHTtT2hL57vdv6VT2w==}
-    engines: {node: ^14.18.0 || >=16.10.0}
-
-  '@nuxt/kit@3.15.0':
-    resolution: {integrity: sha512-Q7k11wDTLIbBgoTfRYNrciK7PvjKklewrKd5PRMJCpn9Lmuqkq59HErNfJXFrBKHsE3Ld0DB6WUtpPGOvWJZoQ==}
+  '@nuxt/kit@3.15.1':
+    resolution: {integrity: sha512-7cVWjzfz3L6CsZrg6ppDZa7zGrZxCSfZjEQDIvVFn4mFKtJlK9k2izf5EewL6luzWwIQojkZAC3iq/1wtgI0Xw==}
     engines: {node: '>=18.20.5'}
 
-  '@nuxt/schema@3.14.1592':
-    resolution: {integrity: sha512-A1d/08ueX8stTXNkvGqnr1eEXZgvKn+vj6s7jXhZNWApUSqMgItU4VK28vrrdpKbjIPwq2SwhnGOHUYvN9HwCQ==}
-    engines: {node: ^14.18.0 || >=16.10.0}
-
   '@nuxt/schema@3.15.0':
     resolution: {integrity: sha512-sAgLgSOj/SZxUmlJ/Q3TLRwIAqmiiZ5gCBrT+eq9CowIj7bgxX92pT720pDLEDs4wlXiTTsqC8nyqXQis8pPyA==}
     engines: {node: ^14.18.0 || >=16.10.0}
 
+  '@nuxt/schema@3.15.1':
+    resolution: {integrity: sha512-n5kOHt8uUyUM9z4Wu/8tIZkBYh3KTCGvyruG6oD9bfeT4OaS21+X3M7XsTXFMe+eYBZA70IFFlWn1JJZIPsKeA==}
+    engines: {node: ^14.18.0 || >=16.10.0}
+
   '@nuxt/telemetry@2.6.2':
     resolution: {integrity: sha512-UReyqp35ZFcsyMuP+DmDj/0W/odANCuObdqYyAIR+/Z/9yDHtBO6Cc/wWbjjhrt41yhhco7/+vILELPHWD+wxg==}
     engines: {node: ^14.18.0 || >=16.10.0}
@@ -1299,9 +1296,9 @@ packages:
   '@nuxt/ui@2.19.1':
     resolution: {integrity: sha512-uGTia2Yz5WyswDxvm7wqYV7ec/TiojdwSjkz/Jx7/+iIqem9aqO8AQ0BvXLBg3q7kGSb9HXo/kwx5JpK1S54JA==}
 
-  '@nuxt/vite-builder@3.14.1592':
-    resolution: {integrity: sha512-GVS7vkBJAGv13ghmjgGrS2QVyzoqxQ5+cAUrMeMjKbY7GnRY7/uOkoLmznYx8E/U9HBUyHQa+wSN2ZfcSiEytQ==}
-    engines: {node: ^14.18.0 || >=16.10.0}
+  '@nuxt/vite-builder@3.15.1':
+    resolution: {integrity: sha512-b9uvLuRSgZy+pvU0rwHOpYo9XmAPibNGFEn0MeG6rUWVee9didV0Q5voAr+/1kq9bIbf6V0QFh9TE+4pCxZuMQ==}
+    engines: {node: ^18.20.5 || ^20.9.0 || >=22.0.0}
     peerDependencies:
       vue: ^3.3.4
 
@@ -2790,9 +2787,6 @@ packages:
     resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
     engines: {node: '>=4'}
 
-  clear@0.1.0:
-    resolution: {integrity: sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw==}
-
   clipboardy@4.0.0:
     resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==}
     engines: {node: '>=18'}
@@ -3900,9 +3894,6 @@ packages:
     resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
     engines: {node: '>= 0.4'}
 
-  hash-sum@2.0.0:
-    resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
-
   hasown@2.0.2:
     resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
     engines: {node: '>= 0.4'}
@@ -4007,10 +3998,6 @@ packages:
     resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
     engines: {node: '>= 4'}
 
-  ignore@6.0.2:
-    resolution: {integrity: sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==}
-    engines: {node: '>= 4'}
-
   ignore@7.0.0:
     resolution: {integrity: sha512-lcX8PNQygAa22u/0BysEY8VhaFRzlOkvdlKczDPnJvrkJD1EuqzEky5VYYKM2iySIuaVIDv9N190DfSreSLw2A==}
     engines: {node: '>= 4'}
@@ -4836,16 +4823,16 @@ packages:
     peerDependencies:
       prettier: ^2.5.x || 3.x
 
-  nuxt-zod-i18n@1.11.2:
-    resolution: {integrity: sha512-lfZIJ4xNx4BRW9iqoAS4aXm7vspMqX3SwQZ8QKhR1jSzZYMEe1Qfl31gJadh/in4MtFXzdbfaaCTrCuKBWSBMA==}
+  nuxt-zod-i18n@1.11.4:
+    resolution: {integrity: sha512-Z3dzma45jRgLruoJii8feu1iRNRCMdifv6xmPvg4GjMmI9P7cCOCkpWAg1KpEtGy+ArroXM4RfEX3CIiHNRAcg==}
 
-  nuxt@3.14.1592:
-    resolution: {integrity: sha512-roWAQH4Mb6WY72cNos+YVw0DgTCNAhNygiAMCedM7hbX6ESTR2n3VH7tU0yIWDPe/hfFdii4M4wWTTNHOtS44g==}
-    engines: {node: ^14.18.0 || >=16.10.0}
+  nuxt@3.15.1:
+    resolution: {integrity: sha512-8sKgqjhu5JoaVv89TnBW5S0jvsXRrEWGF+CguYUPK+6sRAtNcJAwcWxd4pEmURYQ2D0jjdfgr/VyH0i9CdhkBQ==}
+    engines: {node: ^18.20.5 || ^20.9.0 || >=22.0.0}
     hasBin: true
     peerDependencies:
       '@parcel/watcher': ^2.1.0
-      '@types/node': ^14.18.0 || >=16.10.0
+      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
     peerDependenciesMeta:
       '@parcel/watcher':
         optional: true
@@ -5039,6 +5026,9 @@ packages:
   pathe@1.1.2:
     resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
 
+  pathe@2.0.0:
+    resolution: {integrity: sha512-G7n4uhtk9qJt2hlD+UFfsIGY854wpF+zs2bUbQ3CQEUTcn7v25LRsrmurOxTo4bJgjE4qkyshd9ldsEuY9M6xg==}
+
   pbf@3.3.0:
     resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==}
     hasBin: true
@@ -5088,6 +5078,9 @@ packages:
   pkg-types@1.2.1:
     resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==}
 
+  pkg-types@1.3.0:
+    resolution: {integrity: sha512-kS7yWjVFCkIw9hqdJBoMxDdzEngmkr5FXeWZZfQ6GoYacjVnsW6l2CcYW/0ThD0vF4LPJgVYnrg4d0uuhwYQbg==}
+
   pluralize@8.0.0:
     resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
     engines: {node: '>=4'}
@@ -5720,6 +5713,19 @@ packages:
       rollup:
         optional: true
 
+  rollup-plugin-visualizer@5.13.1:
+    resolution: {integrity: sha512-vMg8i6BprL8aFm9DKvL2c8AwS8324EgymYQo9o6E26wgVvwMhsJxS37aNL6ZsU7X9iAcMYwdME7gItLfG5fwJg==}
+    engines: {node: '>=18'}
+    hasBin: true
+    peerDependencies:
+      rolldown: 1.x
+      rollup: 2.x || 3.x || 4.x
+    peerDependenciesMeta:
+      rolldown:
+        optional: true
+      rollup:
+        optional: true
+
   rollup@4.29.1:
     resolution: {integrity: sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -5747,8 +5753,8 @@ packages:
   safer-buffer@2.1.2:
     resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
 
-  sass@1.83.0:
-    resolution: {integrity: sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==}
+  sass@1.83.1:
+    resolution: {integrity: sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==}
     engines: {node: '>=14.0.0'}
     hasBin: true
 
@@ -6285,6 +6291,10 @@ packages:
     resolution: {integrity: sha512-us4j03/499KhbGP8BU7Hrzrgseo+KdfJYWcbcajCOqsAyb8Gk0Yn2kiUIcZISYCb1JFaZfIuG3b42HmguVOKCQ==}
     engines: {node: '>=18.12.0'}
 
+  unplugin@2.1.2:
+    resolution: {integrity: sha512-Q3LU0e4zxKfRko1wMV2HmP8lB9KWislY7hxXpxd+lGx0PRInE4vhMBVEZwpdVYHvtqzhSrzuIfErsob6bQfCzw==}
+    engines: {node: '>=18.12.0'}
+
   unstorage@1.14.1:
     resolution: {integrity: sha512-0MBKpoVhNLL/Ixvue9lIsrHkwwWW9/f3TRftsYu1R7nZJJyHSdgPMBDjny2op07nirnS3OX6H3u+YDFGld+1Bg==}
     peerDependencies:
@@ -6344,6 +6354,65 @@ packages:
       uploadthing:
         optional: true
 
+  unstorage@1.14.4:
+    resolution: {integrity: sha512-1SYeamwuYeQJtJ/USE1x4l17LkmQBzg7deBJ+U9qOBoHo15d1cDxG4jM31zKRgF7pG0kirZy4wVMX6WL6Zoscg==}
+    peerDependencies:
+      '@azure/app-configuration': ^1.8.0
+      '@azure/cosmos': ^4.2.0
+      '@azure/data-tables': ^13.3.0
+      '@azure/identity': ^4.5.0
+      '@azure/keyvault-secrets': ^4.9.0
+      '@azure/storage-blob': ^12.26.0
+      '@capacitor/preferences': ^6.0.3
+      '@deno/kv': '>=0.8.4'
+      '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0
+      '@planetscale/database': ^1.19.0
+      '@upstash/redis': ^1.34.3
+      '@vercel/blob': '>=0.27.0'
+      '@vercel/kv': ^1.0.1
+      aws4fetch: ^1.0.20
+      db0: '>=0.2.1'
+      idb-keyval: ^6.2.1
+      ioredis: ^5.4.2
+      uploadthing: ^7.4.1
+    peerDependenciesMeta:
+      '@azure/app-configuration':
+        optional: true
+      '@azure/cosmos':
+        optional: true
+      '@azure/data-tables':
+        optional: true
+      '@azure/identity':
+        optional: true
+      '@azure/keyvault-secrets':
+        optional: true
+      '@azure/storage-blob':
+        optional: true
+      '@capacitor/preferences':
+        optional: true
+      '@deno/kv':
+        optional: true
+      '@netlify/blobs':
+        optional: true
+      '@planetscale/database':
+        optional: true
+      '@upstash/redis':
+        optional: true
+      '@vercel/blob':
+        optional: true
+      '@vercel/kv':
+        optional: true
+      aws4fetch:
+        optional: true
+      db0:
+        optional: true
+      idb-keyval:
+        optional: true
+      ioredis:
+        optional: true
+      uploadthing:
+        optional: true
+
   untun@0.1.3:
     resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==}
     hasBin: true
@@ -6379,8 +6448,8 @@ packages:
   util-deprecate@1.0.2:
     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
-  uuid@11.0.3:
-    resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==}
+  uuid@11.0.4:
+    resolution: {integrity: sha512-IzL6VtTTYcAhA/oghbFJ1Dkmqev+FpQWnCBaKq/gUluLxliWvO8DPFWfIviRmYbtaavtSQe4WBL++rFjdcGWEg==}
     hasBin: true
 
   uuid@9.0.1:
@@ -6512,6 +6581,46 @@ packages:
       terser:
         optional: true
 
+  vite@6.0.7:
+    resolution: {integrity: sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==}
+    engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+      jiti: '>=1.21.0'
+      less: '*'
+      lightningcss: ^1.21.0
+      sass: '*'
+      sass-embedded: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.16.0
+      tsx: ^4.8.1
+      yaml: ^2.4.2
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      jiti:
+        optional: true
+      less:
+        optional: true
+      lightningcss:
+        optional: true
+      sass:
+        optional: true
+      sass-embedded:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+      tsx:
+        optional: true
+      yaml:
+        optional: true
+
   vscode-jsonrpc@6.0.0:
     resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==}
     engines: {node: '>=8.0.0 || >=10.0.0'}
@@ -7357,7 +7466,7 @@ snapshots:
 
   '@galexrt/nuxt-update@1.0.1(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       defu: 6.1.4
       mitt: 3.0.1
     transitivePeerDependencies:
@@ -7662,13 +7771,13 @@ snapshots:
       '@nodelib/fs.scandir': 3.0.0
       fastq: 1.18.0
 
-  '@nuxt/content@2.13.4(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/content@2.13.4(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@nuxtjs/mdc': 0.9.5(magicast@0.3.5)(rollup@4.29.1)
       '@vueuse/core': 11.3.0(vue@3.5.13(typescript@5.7.2))
       '@vueuse/head': 2.0.0(vue@3.5.13(typescript@5.7.2))
-      '@vueuse/nuxt': 11.3.0(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
+      '@vueuse/nuxt': 11.3.0(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
       consola: 3.3.3
       defu: 6.1.4
       destr: 2.0.3
@@ -7721,23 +7830,23 @@ snapshots:
 
   '@nuxt/devalue@2.0.2': {}
 
-  '@nuxt/devtools-kit@1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))':
+  '@nuxt/devtools-kit@1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@nuxt/schema': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
       execa: 7.2.0
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
     transitivePeerDependencies:
       - magicast
       - rollup
       - supports-color
 
-  '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))':
+  '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@nuxt/schema': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
       execa: 7.2.0
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
     transitivePeerDependencies:
       - magicast
       - rollup
@@ -7756,13 +7865,13 @@ snapshots:
       rc9: 2.1.2
       semver: 7.6.3
 
-  '@nuxt/devtools@1.7.0(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/devtools@1.7.0(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@antfu/utils': 0.7.10
-      '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+      '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       '@nuxt/devtools-wizard': 1.7.0
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
-      '@vue/devtools-core': 7.6.8(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
+      '@vue/devtools-core': 7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       '@vue/devtools-kit': 7.6.8
       birpc: 0.2.19
       consola: 3.3.3
@@ -7791,9 +7900,9 @@ snapshots:
       sirv: 3.0.0
       tinyglobby: 0.2.10
       unimport: 3.14.5(rollup@4.29.1)
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
-      vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.0(magicast@0.3.5)(rollup@4.29.1))(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
-      vite-plugin-vue-inspector: 5.3.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
+      vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.29.1))(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
+      vite-plugin-vue-inspector: 5.3.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       which: 3.0.1
       ws: 8.18.0
     transitivePeerDependencies:
@@ -7840,13 +7949,13 @@ snapshots:
       - supports-color
       - typescript
 
-  '@nuxt/eslint@0.7.4(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))':
+  '@nuxt/eslint@0.7.4(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))':
     dependencies:
       '@eslint/config-inspector': 0.6.0(eslint@9.17.0(jiti@2.4.2))
-      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       '@nuxt/eslint-config': 0.7.4(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)
       '@nuxt/eslint-plugin': 0.7.4(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       chokidar: 4.0.3
       eslint: 9.17.0(jiti@2.4.2)
       eslint-flat-config-utils: 0.4.0
@@ -7867,10 +7976,10 @@ snapshots:
       - utf-8-validate
       - vite
 
-  '@nuxt/fonts@0.10.3(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))':
+  '@nuxt/fonts@0.10.3(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))':
     dependencies:
-      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       chalk: 5.4.1
       css-tree: 3.1.0
       defu: 6.1.4
@@ -7914,14 +8023,14 @@ snapshots:
       - uploadthing
       - vite
 
-  '@nuxt/icon@1.10.3(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/icon@1.10.3(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@iconify/collections': 1.0.499
       '@iconify/types': 2.0.0
       '@iconify/utils': 2.2.1
       '@iconify/vue': 4.2.0(vue@3.5.13(typescript@5.7.2))
-      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       consola: 3.3.3
       local-pkg: 0.5.1
       mlly: 1.7.3
@@ -7937,36 +8046,9 @@ snapshots:
       - vite
       - vue
 
-  '@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@4.29.1)':
-    dependencies:
-      '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.29.1)
-      c12: 2.0.1(magicast@0.3.5)
-      consola: 3.3.3
-      defu: 6.1.4
-      destr: 2.0.3
-      globby: 14.0.2
-      hash-sum: 2.0.0
-      ignore: 6.0.2
-      jiti: 2.4.2
-      klona: 2.0.6
-      knitwork: 1.2.0
-      mlly: 1.7.3
-      pathe: 1.1.2
-      pkg-types: 1.2.1
-      scule: 1.3.0
-      semver: 7.6.3
-      ufo: 1.5.4
-      unctx: 2.4.1
-      unimport: 3.14.5(rollup@4.29.1)
-      untyped: 1.5.2
-    transitivePeerDependencies:
-      - magicast
-      - rollup
-      - supports-color
-
-  '@nuxt/kit@3.15.0(magicast@0.3.5)(rollup@4.29.1)':
+  '@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/schema': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/schema': 3.15.1
       c12: 2.0.1(magicast@0.3.5)
       consola: 3.3.3
       defu: 6.1.4
@@ -7978,8 +8060,8 @@ snapshots:
       knitwork: 1.2.0
       mlly: 1.7.3
       ohash: 1.1.4
-      pathe: 1.1.2
-      pkg-types: 1.2.1
+      pathe: 2.0.0
+      pkg-types: 1.3.0
       scule: 1.3.0
       semver: 7.6.3
       ufo: 1.5.4
@@ -7991,7 +8073,7 @@ snapshots:
       - rollup
       - supports-color
 
-  '@nuxt/schema@3.14.1592(magicast@0.3.5)(rollup@4.29.1)':
+  '@nuxt/schema@3.15.0(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
       c12: 2.0.1(magicast@0.3.5)
       compatx: 0.1.8
@@ -8011,29 +8093,16 @@ snapshots:
       - rollup
       - supports-color
 
-  '@nuxt/schema@3.15.0(magicast@0.3.5)(rollup@4.29.1)':
+  '@nuxt/schema@3.15.1':
     dependencies:
-      c12: 2.0.1(magicast@0.3.5)
-      compatx: 0.1.8
       consola: 3.3.3
       defu: 6.1.4
-      hookable: 5.5.3
-      pathe: 1.1.2
-      pkg-types: 1.2.1
-      scule: 1.3.0
+      pathe: 2.0.0
       std-env: 3.8.0
-      ufo: 1.5.4
-      uncrypto: 0.1.3
-      unimport: 3.14.5(rollup@4.29.1)
-      untyped: 1.5.2
-    transitivePeerDependencies:
-      - magicast
-      - rollup
-      - supports-color
 
   '@nuxt/telemetry@2.6.2(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       citty: 0.1.6
       consola: 3.3.3
       destr: 2.0.3
@@ -8052,10 +8121,10 @@ snapshots:
       - rollup
       - supports-color
 
-  '@nuxt/ui-pro@1.6.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/ui-pro@1.6.0(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@iconify-json/vscode-icons': 1.2.6
-      '@nuxt/ui': 2.19.1(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+      '@nuxt/ui': 2.19.1(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       '@vueuse/core': 12.3.0(typescript@5.7.2)
       defu: 6.1.4
       git-url-parse: 16.0.0
@@ -8086,13 +8155,13 @@ snapshots:
       - vite
       - vue
 
-  '@nuxt/ui@2.19.1(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/ui@2.19.1(change-case@5.4.4)(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@headlessui/tailwindcss': 0.2.1(tailwindcss@3.4.17)
       '@headlessui/vue': 1.7.23(vue@3.5.13(typescript@5.7.2))
       '@iconify-json/heroicons': 1.2.2
-      '@nuxt/icon': 1.10.3(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/icon': 1.10.3(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@nuxtjs/color-mode': 3.5.2(magicast@0.3.5)(rollup@4.29.1)
       '@nuxtjs/tailwindcss': 6.12.2(magicast@0.3.5)(rollup@4.29.1)
       '@popperjs/core': 2.11.8
@@ -8130,20 +8199,18 @@ snapshots:
       - vite
       - vue
 
-  '@nuxt/vite-builder@3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxt/vite-builder@3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))(yaml@2.6.1)':
     dependencies:
-      '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@rollup/plugin-replace': 6.0.2(rollup@4.29.1)
-      '@vitejs/plugin-vue': 5.2.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
-      '@vitejs/plugin-vue-jsx': 4.1.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+      '@vitejs/plugin-vue': 5.2.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
+      '@vitejs/plugin-vue-jsx': 4.1.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       autoprefixer: 10.4.20(postcss@8.4.49)
-      clear: 0.1.0
       consola: 3.3.3
       cssnano: 7.0.6(postcss@8.4.49)
       defu: 6.1.4
       esbuild: 0.24.2
       escape-string-regexp: 5.0.0
-      estree-walker: 3.0.3
       externality: 1.0.2
       get-port-please: 3.1.2
       h3: 1.13.0
@@ -8152,19 +8219,18 @@ snapshots:
       magic-string: 0.30.17
       mlly: 1.7.3
       ohash: 1.1.4
-      pathe: 1.1.2
+      pathe: 2.0.0
       perfect-debounce: 1.0.0
-      pkg-types: 1.2.1
+      pkg-types: 1.3.0
       postcss: 8.4.49
-      rollup-plugin-visualizer: 5.12.0(rollup@4.29.1)
+      rollup-plugin-visualizer: 5.13.1(rollup@4.29.1)
       std-env: 3.8.0
-      strip-literal: 2.1.1
       ufo: 1.5.4
       unenv: 1.10.0
-      unplugin: 1.16.0
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
-      vite-node: 2.1.8(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
-      vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2))
+      unplugin: 2.1.2
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
+      vite-node: 2.1.8(@types/node@22.10.5)(sass@1.83.1)(terser@5.37.0)
+      vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))
       vue: 3.5.13(typescript@5.7.2)
       vue-bundle-renderer: 2.1.1
     transitivePeerDependencies:
@@ -8176,6 +8242,7 @@ snapshots:
       - magicast
       - meow
       - optionator
+      - rolldown
       - rollup
       - sass
       - sass-embedded
@@ -8184,16 +8251,18 @@ snapshots:
       - sugarss
       - supports-color
       - terser
+      - tsx
       - typescript
       - vls
       - vti
       - vue-tsc
+      - yaml
 
   '@nuxtjs/color-mode@3.5.2(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       pathe: 1.1.2
-      pkg-types: 1.2.1
+      pkg-types: 1.3.0
       semver: 7.6.3
     transitivePeerDependencies:
       - magicast
@@ -8202,7 +8271,7 @@ snapshots:
 
   '@nuxtjs/fontaine@0.4.4(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       fontaine: 0.5.0
       magic-string: 0.30.17
       pathe: 1.1.2
@@ -8220,7 +8289,7 @@ snapshots:
       '@intlify/unplugin-vue-i18n': 6.0.2(@vue/compiler-dom@3.5.13)(eslint@9.17.0(jiti@2.4.2))(rollup@4.29.1)(typescript@5.7.2)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
       '@intlify/utils': 0.13.0
       '@miyaneee/rollup-plugin-json5': 1.2.0(rollup@4.29.1)
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@rollup/plugin-yaml': 4.1.2(rollup@4.29.1)
       '@vue/compiler-sfc': 3.5.13
       debug: 4.4.0(supports-color@9.4.0)
@@ -8250,7 +8319,7 @@ snapshots:
 
   '@nuxtjs/mdc@0.9.5(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@shikijs/transformers': 1.24.4
       '@types/hast': 3.0.4
       '@types/mdast': 4.0.4
@@ -8291,13 +8360,13 @@ snapshots:
       - rollup
       - supports-color
 
-  '@nuxtjs/robots@5.1.0(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@nuxtjs/robots@5.1.0(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
-      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       consola: 3.3.3
       defu: 6.1.4
-      nuxt-site-config: 3.0.6(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
+      nuxt-site-config: 3.0.6(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
       pathe: 1.1.2
       pkg-types: 1.2.1
       sirv: 3.0.0
@@ -8312,7 +8381,7 @@ snapshots:
 
   '@nuxtjs/tailwindcss@6.12.2(magicast@0.3.5)(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       autoprefixer: 10.4.20(postcss@8.4.49)
       consola: 3.3.3
       defu: 6.1.4
@@ -8398,7 +8467,7 @@ snapshots:
 
   '@pinia/nuxt@0.9.0(magicast@0.3.5)(pinia@2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)))(rollup@4.29.1)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       pinia: 2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))
     transitivePeerDependencies:
       - magicast
@@ -9358,19 +9427,19 @@ snapshots:
       - rollup
       - supports-color
 
-  '@vitejs/plugin-vue-jsx@4.1.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@vitejs/plugin-vue-jsx@4.1.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@babel/core': 7.26.0
       '@babel/plugin-transform-typescript': 7.26.3(@babel/core@7.26.0)
       '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0)
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
       vue: 3.5.13(typescript@5.7.2)
     transitivePeerDependencies:
       - supports-color
 
-  '@vitejs/plugin-vue@5.2.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@vitejs/plugin-vue@5.2.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
       vue: 3.5.13(typescript@5.7.2)
 
   '@volar/language-core@2.4.11':
@@ -9487,14 +9556,14 @@ snapshots:
 
   '@vue/devtools-api@6.6.4': {}
 
-  '@vue/devtools-core@7.6.8(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))':
+  '@vue/devtools-core@7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))':
     dependencies:
       '@vue/devtools-kit': 7.6.8
       '@vue/devtools-shared': 7.6.8
       mitt: 3.0.1
       nanoid: 5.0.9
       pathe: 1.1.2
-      vite-hot-client: 0.2.4(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
+      vite-hot-client: 0.2.4(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
       vue: 3.5.13(typescript@5.7.2)
     transitivePeerDependencies:
       - vite
@@ -9601,13 +9670,13 @@ snapshots:
 
   '@vueuse/metadata@12.3.0': {}
 
-  '@vueuse/nuxt@11.3.0(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))':
+  '@vueuse/nuxt@11.3.0(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@vueuse/core': 11.3.0(vue@3.5.13(typescript@5.7.2))
       '@vueuse/metadata': 11.3.0
       local-pkg: 0.5.1
-      nuxt: 3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2))
+      nuxt: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1)
       vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.2))
     transitivePeerDependencies:
       - '@vue/composition-api'
@@ -9616,13 +9685,13 @@ snapshots:
       - supports-color
       - vue
 
-  '@vueuse/nuxt@12.3.0(magicast@0.3.5)(nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)))(rollup@4.29.1)(typescript@5.7.2)':
+  '@vueuse/nuxt@12.3.0(magicast@0.3.5)(nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1))(rollup@4.29.1)(typescript@5.7.2)':
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@vueuse/core': 12.3.0(typescript@5.7.2)
       '@vueuse/metadata': 12.3.0
       local-pkg: 0.5.1
-      nuxt: 3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2))
+      nuxt: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1)
       vue: 3.5.13(typescript@5.7.2)
     transitivePeerDependencies:
       - magicast
@@ -9950,8 +10019,6 @@ snapshots:
     dependencies:
       escape-string-regexp: 1.0.5
 
-  clear@0.1.0: {}
-
   clipboardy@4.0.0:
     dependencies:
       execa: 8.0.1
@@ -11149,8 +11216,6 @@ snapshots:
     dependencies:
       has-symbols: 1.1.0
 
-  hash-sum@2.0.0: {}
-
   hasown@2.0.2:
     dependencies:
       function-bind: 1.1.2
@@ -11299,8 +11364,6 @@ snapshots:
 
   ignore@5.3.2: {}
 
-  ignore@6.0.2: {}
-
   ignore@7.0.0: {}
 
   image-meta@0.2.1: {}
@@ -12243,7 +12306,7 @@ snapshots:
       openapi-typescript: 7.4.4(typescript@5.7.2)
       pathe: 1.1.2
       perfect-debounce: 1.0.0
-      pkg-types: 1.2.1
+      pkg-types: 1.3.0
       pretty-bytes: 6.1.1
       radix3: 1.1.2
       rollup: 4.29.1
@@ -12258,7 +12321,7 @@ snapshots:
       unctx: 2.4.1
       unenv: 1.10.0
       unimport: 3.14.5(rollup@4.29.1)
-      unstorage: 1.14.1(db0@0.2.1)(ioredis@5.4.2)
+      unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2)
       untyped: 1.5.2
       unwasm: 0.3.9
     transitivePeerDependencies:
@@ -12347,9 +12410,9 @@ snapshots:
 
   nuxt-site-config-kit@3.0.6(magicast@0.3.5)(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2)):
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
-      '@nuxt/schema': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
-      pkg-types: 1.2.1
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/schema': 3.15.1
+      pkg-types: 1.3.0
       site-config-stack: 3.0.6(vue@3.5.13(typescript@5.7.2))
       std-env: 3.8.0
       ufo: 1.5.4
@@ -12359,10 +12422,10 @@ snapshots:
       - supports-color
       - vue
 
-  nuxt-site-config@3.0.6(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2)):
+  nuxt-site-config@3.0.6(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)):
     dependencies:
-      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/devtools-kit': 1.6.4(magicast@0.3.5)(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@nuxt/schema': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
       nuxt-site-config-kit: 3.0.6(magicast@0.3.5)(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2))
       pathe: 1.1.2
@@ -12379,7 +12442,7 @@ snapshots:
 
   nuxt-tiptap-editor@2.1.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/extension-code-block@2.10.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/pm@2.10.4))(highlight.js@11.11.0)(magicast@0.3.5)(rollup@4.29.1)(vue@3.5.13(typescript@5.7.2)):
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       '@tiptap/extension-code-block-lowlight': 2.10.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/extension-code-block@2.10.4(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/pm@2.10.4))(@tiptap/pm@2.10.4)(highlight.js@11.11.0)(lowlight@3.3.0)
       '@tiptap/extension-image': 2.11.0(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))
       '@tiptap/extension-link': 2.11.0(@tiptap/core@2.10.4(@tiptap/pm@2.10.4))(@tiptap/pm@2.10.4)
@@ -12399,7 +12462,7 @@ snapshots:
 
   nuxt-typed-router@3.7.2(magicast@0.3.5)(prettier@3.4.2)(rollup@4.29.1):
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       chalk: 5.3.0
       defu: 6.1.4
       lodash-es: 4.17.21
@@ -12413,26 +12476,28 @@ snapshots:
       - rollup
       - supports-color
 
-  nuxt-zod-i18n@1.11.2(magicast@0.3.5)(rollup@4.29.1):
+  nuxt-zod-i18n@1.11.4(magicast@0.3.5)(rollup@4.29.1)(typescript@5.7.2):
     dependencies:
-      '@intlify/shared': 9.14.2
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@intlify/shared': 11.0.1
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       dedupe: 4.0.3
       defu: 6.1.4
+      vue-tsc: 2.2.0(typescript@5.7.2)
       zod: 3.24.1
     transitivePeerDependencies:
       - magicast
       - rollup
       - supports-color
+      - typescript
 
-  nuxt@3.14.1592(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)):
+  nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.6.1):
     dependencies:
       '@nuxt/devalue': 2.0.2
-      '@nuxt/devtools': 1.7.0(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2))
-      '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.29.1)
-      '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/devtools': 1.7.0(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/schema': 3.15.1
       '@nuxt/telemetry': 2.6.2(magicast@0.3.5)(rollup@4.29.1)
-      '@nuxt/vite-builder': 3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.0)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))
+      '@nuxt/vite-builder': 3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.29.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))(yaml@2.6.1)
       '@unhead/dom': 1.11.14
       '@unhead/shared': 1.11.14
       '@unhead/ssr': 1.11.14
@@ -12454,7 +12519,7 @@ snapshots:
       globby: 14.0.2
       h3: 1.13.0
       hookable: 5.5.3
-      ignore: 6.0.2
+      ignore: 7.0.0
       impound: 0.2.0(rollup@4.29.1)
       jiti: 2.4.2
       klona: 2.0.6
@@ -12464,12 +12529,12 @@ snapshots:
       nanotar: 0.1.1
       nitropack: 2.10.4(typescript@5.7.2)
       nuxi: 3.17.2
-      nypm: 0.3.12
+      nypm: 0.4.1
       ofetch: 1.4.1
       ohash: 1.1.4
-      pathe: 1.1.2
+      pathe: 2.0.0
       perfect-debounce: 1.0.0
-      pkg-types: 1.2.1
+      pkg-types: 1.3.0
       radix3: 1.1.2
       scule: 1.3.0
       semver: 7.6.3
@@ -12483,9 +12548,9 @@ snapshots:
       unenv: 1.10.0
       unhead: 1.11.14
       unimport: 3.14.5(rollup@4.29.1)
-      unplugin: 1.16.0
+      unplugin: 2.1.2
       unplugin-vue-router: 0.10.9(rollup@4.29.1)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
-      unstorage: 1.14.1(db0@0.2.1)(ioredis@5.4.2)
+      unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2)
       untyped: 1.5.2
       vue: 3.5.13(typescript@5.7.2)
       vue-bundle-renderer: 2.1.1
@@ -12526,6 +12591,7 @@ snapshots:
       - meow
       - mysql2
       - optionator
+      - rolldown
       - rollup
       - sass
       - sass-embedded
@@ -12534,6 +12600,7 @@ snapshots:
       - sugarss
       - supports-color
       - terser
+      - tsx
       - typescript
       - uploadthing
       - utf-8-validate
@@ -12542,6 +12609,7 @@ snapshots:
       - vti
       - vue-tsc
       - xml2js
+      - yaml
 
   nypm@0.3.12:
     dependencies:
@@ -12747,6 +12815,8 @@ snapshots:
 
   pathe@1.1.2: {}
 
+  pathe@2.0.0: {}
+
   pbf@3.3.0:
     dependencies:
       ieee754: 1.2.1
@@ -12764,7 +12834,7 @@ snapshots:
 
   pinia-plugin-persistedstate@4.2.0(@pinia/nuxt@0.9.0(magicast@0.3.5)(pinia@2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)))(rollup@4.29.1))(magicast@0.3.5)(pinia@2.3.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)))(rollup@4.29.1):
     dependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
       deep-pick-omit: 1.2.1
       defu: 6.1.4
       destr: 2.0.3
@@ -12794,6 +12864,12 @@ snapshots:
       mlly: 1.7.3
       pathe: 1.1.2
 
+  pkg-types@1.3.0:
+    dependencies:
+      confbox: 0.1.8
+      mlly: 1.7.3
+      pathe: 1.1.2
+
   pluralize@8.0.0: {}
 
   portfinder@1.0.32:
@@ -13461,6 +13537,15 @@ snapshots:
     optionalDependencies:
       rollup: 4.29.1
 
+  rollup-plugin-visualizer@5.13.1(rollup@4.29.1):
+    dependencies:
+      open: 8.4.2
+      picomatch: 4.0.2
+      source-map: 0.7.4
+      yargs: 17.7.2
+    optionalDependencies:
+      rollup: 4.29.1
+
   rollup@4.29.1:
     dependencies:
       '@types/estree': 1.0.6
@@ -13502,7 +13587,7 @@ snapshots:
 
   safer-buffer@2.1.2: {}
 
-  sass@1.83.0:
+  sass@1.83.1:
     dependencies:
       chokidar: 4.0.3
       immutable: 5.0.3
@@ -14127,6 +14212,11 @@ snapshots:
       acorn: 8.14.0
       webpack-virtual-modules: 0.6.2
 
+  unplugin@2.1.2:
+    dependencies:
+      acorn: 8.14.0
+      webpack-virtual-modules: 0.6.2
+
   unstorage@1.14.1(db0@0.2.1)(ioredis@5.4.2):
     dependencies:
       anymatch: 3.1.3
@@ -14143,6 +14233,20 @@ snapshots:
       db0: 0.2.1
       ioredis: 5.4.2
 
+  unstorage@1.14.4(db0@0.2.1)(ioredis@5.4.2):
+    dependencies:
+      anymatch: 3.1.3
+      chokidar: 3.6.0
+      destr: 2.0.3
+      h3: 1.13.0
+      lru-cache: 10.4.3
+      node-fetch-native: 1.6.4
+      ofetch: 1.4.1
+      ufo: 1.5.4
+    optionalDependencies:
+      db0: 0.2.1
+      ioredis: 5.4.2
+
   untun@0.1.3:
     dependencies:
       citty: 0.1.6
@@ -14202,7 +14306,7 @@ snapshots:
 
   util-deprecate@1.0.2: {}
 
-  uuid@11.0.3: {}
+  uuid@11.0.4: {}
 
   uuid@9.0.1: {}
 
@@ -14256,17 +14360,17 @@ snapshots:
       remove-trailing-separator: 1.1.0
       replace-ext: 1.0.1
 
-  vite-hot-client@0.2.4(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)):
+  vite-hot-client@0.2.4(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)):
     dependencies:
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
 
-  vite-node@2.1.8(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0):
+  vite-node@2.1.8(@types/node@22.10.5)(sass@1.83.1)(terser@5.37.0):
     dependencies:
       cac: 6.7.14
       debug: 4.4.0(supports-color@9.4.0)
       es-module-lexer: 1.5.4
       pathe: 1.1.2
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.1)(terser@5.37.0)
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -14278,7 +14382,7 @@ snapshots:
       - supports-color
       - terser
 
-  vite-plugin-checker@0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0))(vue-tsc@2.2.0(typescript@5.7.2)):
+  vite-plugin-checker@0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1))(vue-tsc@2.2.0(typescript@5.7.2)):
     dependencies:
       '@babel/code-frame': 7.26.2
       ansi-escapes: 4.3.2
@@ -14290,7 +14394,7 @@ snapshots:
       npm-run-path: 4.0.1
       strip-ansi: 6.0.1
       tiny-invariant: 1.3.3
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
       vscode-languageclient: 7.0.0
       vscode-languageserver: 7.0.0
       vscode-languageserver-textdocument: 1.0.12
@@ -14301,7 +14405,7 @@ snapshots:
       typescript: 5.7.2
       vue-tsc: 2.2.0(typescript@5.7.2)
 
-  vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.0(magicast@0.3.5)(rollup@4.29.1))(rollup@4.29.1)(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)):
+  vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.29.1))(rollup@4.29.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)):
     dependencies:
       '@antfu/utils': 0.7.10
       '@rollup/pluginutils': 5.1.4(rollup@4.29.1)
@@ -14312,14 +14416,14 @@ snapshots:
       perfect-debounce: 1.0.0
       picocolors: 1.1.1
       sirv: 3.0.0
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
     optionalDependencies:
-      '@nuxt/kit': 3.15.0(magicast@0.3.5)(rollup@4.29.1)
+      '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.29.1)
     transitivePeerDependencies:
       - rollup
       - supports-color
 
-  vite-plugin-vue-inspector@5.3.1(vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)):
+  vite-plugin-vue-inspector@5.3.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)):
     dependencies:
       '@babel/core': 7.26.0
       '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0)
@@ -14330,11 +14434,11 @@ snapshots:
       '@vue/compiler-dom': 3.5.13
       kolorist: 1.8.0
       magic-string: 0.30.17
-      vite: 5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0)
+      vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1)
     transitivePeerDependencies:
       - supports-color
 
-  vite@5.4.11(@types/node@22.10.5)(sass@1.83.0)(terser@5.37.0):
+  vite@5.4.11(@types/node@22.10.5)(sass@1.83.1)(terser@5.37.0):
     dependencies:
       esbuild: 0.21.5
       postcss: 8.4.49
@@ -14342,9 +14446,22 @@ snapshots:
     optionalDependencies:
       '@types/node': 22.10.5
       fsevents: 2.3.3
-      sass: 1.83.0
+      sass: 1.83.1
       terser: 5.37.0
 
+  vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.6.1):
+    dependencies:
+      esbuild: 0.24.2
+      postcss: 8.4.49
+      rollup: 4.29.1
+    optionalDependencies:
+      '@types/node': 22.10.5
+      fsevents: 2.3.3
+      jiti: 2.4.2
+      sass: 1.83.1
+      terser: 5.37.0
+      yaml: 2.6.1
+
   vscode-jsonrpc@6.0.0: {}
 
   vscode-languageclient@7.0.0: