diff --git a/.gitignore b/.gitignore
index 458da062..35db31f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@
# workspace
go.work
+go.work*
diff --git a/Dockerfile b/Dockerfile
index 6b0e9683..e2ea2a9b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,20 @@
# syntax=docker/dockerfile:1
-
-ARG GO_VERSION=1.21
+# Copyright (C) 2023 Kevin Z
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+ARG GO_VERSION=1.23
ARG REPO=github.com/LiterMC/go-openbmclapi
ARG NPM_DIR=dashboard
@@ -23,6 +37,7 @@ ARG NPM_DIR
WORKDIR "/go/src/${REPO}/"
+ENV CGO_ENABLED=0
COPY ./go.mod ./go.sum "/go/src/${REPO}/"
RUN go mod download
COPY . "/go/src/${REPO}"
@@ -31,7 +46,7 @@ COPY --from=WEB_BUILD "/web/dist" "/go/src/${REPO}/${NPM_DIR}/dist"
ENV ldflags="-X 'github.com/LiterMC/go-openbmclapi/internal/build.BuildVersion=$TAG'"
RUN --mount=type=cache,target=/root/.cache/go-build \
- CGO_ENABLED=0 go build -v -o "/go/bin/go-openbmclapi" -ldflags="$ldflags" "."
+ go build -v -o "/go/bin/go-openbmclapi" -ldflags="$ldflags" "."
FROM alpine:latest
@@ -40,4 +55,4 @@ COPY ./config.yaml /opt/openbmclapi/config.yaml
COPY --from=BUILD "/go/bin/go-openbmclapi" "/go-openbmclapi"
-CMD ["/go-openbmclapi"]
+ENTRYPOINT ["/go-openbmclapi"]
diff --git a/README.MD b/README.MD
index 8454a49a..581470d7 100644
--- a/README.MD
+++ b/README.MD
@@ -63,7 +63,7 @@ A: 请确认中间所有的反向代理都支持 WebSocket
### 无依赖直接运行
1. 从 [Github Release](https://github.com/LiterMC/go-openbmclapi/releases/latest) 找到**适合您服务器平台**的程序并下载到节点服务器上
-2. 配置配置文件, 可以直接使用与bangbang93的openbmclapi相同的环境变量配置, 也可以从`config.yaml`进行配置 _(下文有讲)_
+2. 配置 `config.yaml` 配置文件 _(下文有讲)_
3. 运行程序
### 从docker运行
@@ -79,7 +79,6 @@ A: 请确认中间所有的反向代理都支持 WebSocket
```sh
curl -fsSL https://raw.githubusercontent.com/LiterMC/go-openbmclapi/HEAD/installer/service/installer.sh | sudo bash -s
```
- > 注意, 新版新增使用 `openbmclapi` 用户执行程序, 可能需要执行 `sudo chown -R openbmclapi /opt/openbmclapi` 指令修复权限
国内对 Github 的支持较差, 可以使用 ghproxy 等镜像站运行脚本, 本例中使用了 [crashmc.com](https://crashmc.com) 提供的 CDN:
```sh
@@ -89,7 +88,7 @@ A: 请确认中间所有的反向代理都支持 WebSocket
如果需要下载指定版本, 只需设置 `-t|--tag` 标志即可
```sh
- curl -fsSL https://raw.githubusercontent.com/LiterMC/go-openbmclapi/HEAD/installer/service/installer.sh | sudo bash -s -- --tag v1.9.7-8
+ curl -fsSL https://raw.githubusercontent.com/LiterMC/go-openbmclapi/HEAD/installer/service/installer.sh | sudo bash -s -- --tag v1.13.1-2
```
3. 配置`/opt/openbmclapi/config.yaml`配置文件
4. 使用`systemctl start go-openbmclapi.service`启动服务
@@ -101,7 +100,7 @@ A: 请确认中间所有的反向代理都支持 WebSocket
### 从源代码运行
-1. 确保您的服务器上装有 `go 1.21+` 以及 `node & npm`
+1. 确保您的服务器上装有 `go 1.23+` 以及 `node & npm`
2. 下载本仓库 _(可以使用`git clone https://github.com/LiterMC/go-openbmclapi.git`)_
3. cd 进入本仓库
4. 配置配置文件或环境变量
@@ -176,8 +175,8 @@ tunneler:
# 缓存
cache:
# 缓存类型:
- # nocache: 不缓存
- # inmem: 程序内内存缓存
+ # no-cache: 不缓存
+ # memory: 程序内内存缓存
# redis: Redis 缓存
type: redis
# 如果使用 Redis 缓存则还需要配置用户名密码等:
diff --git a/api.go b/api.go
deleted file mode 100644
index 7d52ddf9..00000000
--- a/api.go
+++ /dev/null
@@ -1,1185 +0,0 @@
-/**
- * OpenBmclAPI (Golang Edition)
- * Copyright (C) 2023 Kevin Z
- * All rights reserved
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "compress/gzip"
- "context"
- "crypto/subtle"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "mime"
- "net/http"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "sync/atomic"
- "time"
-
- "runtime/pprof"
- // "github.com/gorilla/websocket"
- "github.com/google/uuid"
-
- "github.com/LiterMC/go-openbmclapi/database"
- "github.com/LiterMC/go-openbmclapi/internal/build"
- "github.com/LiterMC/go-openbmclapi/limited"
- "github.com/LiterMC/go-openbmclapi/log"
- "github.com/LiterMC/go-openbmclapi/notify"
- "github.com/LiterMC/go-openbmclapi/utils"
-)
-
-const (
- clientIdCookieName = "_id"
-
- clientIdKey = "go-openbmclapi.cluster.client.id"
-)
-
-func apiGetClientId(req *http.Request) (id string) {
- return req.Context().Value(clientIdKey).(string)
-}
-
-func (cr *Cluster) cliIdHandle(next http.Handler) http.Handler {
- return (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
- var id string
- if cid, _ := req.Cookie(clientIdCookieName); cid != nil {
- id = cid.Value
- } else {
- var err error
- id, err = utils.GenRandB64(16)
- if err != nil {
- http.Error(rw, "cannot generate random number", http.StatusInternalServerError)
- return
- }
- http.SetCookie(rw, &http.Cookie{
- Name: clientIdCookieName,
- Value: id,
- Expires: time.Now().Add(time.Hour * 24 * 365 * 16),
- Secure: true,
- HttpOnly: true,
- })
- }
- req = req.WithContext(context.WithValue(req.Context(), clientIdKey, utils.AsSha256(id)))
- next.ServeHTTP(rw, req)
- })
-}
-
-func (cr *Cluster) authMiddleware(rw http.ResponseWriter, req *http.Request, next http.Handler) {
- cli := apiGetClientId(req)
-
- ctx := req.Context()
-
- var (
- id string
- uid string
- err error
- )
- if req.Method == http.MethodGet {
- if tk := req.URL.Query().Get("_t"); tk != "" {
- path := GetRequestRealPath(req)
- if id, uid, err = cr.verifyAPIToken(cli, tk, path, req.URL.Query()); err == nil {
- ctx = context.WithValue(ctx, tokenTypeKey, tokenTypeAPI)
- }
- }
- }
- if id == "" {
- auth := req.Header.Get("Authorization")
- tk, ok := strings.CutPrefix(auth, "Bearer ")
- if !ok {
- if err == nil {
- err = ErrUnsupportAuthType
- }
- } else if id, uid, err = cr.verifyAuthToken(cli, tk); err != nil {
- id = ""
- } else {
- ctx = context.WithValue(ctx, tokenTypeKey, tokenTypeAuth)
- }
- }
- if id != "" {
- ctx = context.WithValue(ctx, loggedUserKey, uid)
- ctx = context.WithValue(ctx, tokenIdKey, id)
- req = req.WithContext(ctx)
- }
- next.ServeHTTP(rw, req)
-}
-
-func (cr *Cluster) apiAuthHandle(next http.Handler) http.Handler {
- return (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
- if req.Context().Value(tokenTypeKey) == nil {
- writeJson(rw, http.StatusUnauthorized, Map{
- "error": "403 Unauthorized",
- })
- return
- }
- next.ServeHTTP(rw, req)
- })
-}
-
-func (cr *Cluster) apiAuthHandleFunc(next http.HandlerFunc) http.Handler {
- return cr.apiAuthHandle(next)
-}
-
-func (cr *Cluster) initAPIv0() http.Handler {
- mux := http.NewServeMux()
- mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "404 not found",
- "path": req.URL.Path,
- })
- })
-
- mux.HandleFunc("/ping", cr.apiV1Ping)
- mux.HandleFunc("/status", cr.apiV0Status)
- mux.Handle("/stat/", http.StripPrefix("/stat/", (http.HandlerFunc)(cr.apiV0Stat)))
-
- mux.HandleFunc("/challenge", cr.apiV1Challenge)
- mux.HandleFunc("/login", cr.apiV0Login)
- mux.Handle("/requestToken", cr.apiAuthHandleFunc(cr.apiV0RequestToken))
- mux.Handle("/logout", cr.apiAuthHandleFunc(cr.apiV1Logout))
-
- mux.HandleFunc("/log.io", cr.apiV1LogIO)
- mux.Handle("/pprof", cr.apiAuthHandleFunc(cr.apiV1Pprof))
- mux.HandleFunc("/subscribeKey", cr.apiV0SubscribeKey)
- mux.Handle("/subscribe", cr.apiAuthHandleFunc(cr.apiV0Subscribe))
- mux.Handle("/subscribe_email", cr.apiAuthHandleFunc(cr.apiV0SubscribeEmail))
- mux.Handle("/webhook", cr.apiAuthHandleFunc(cr.apiV0Webhook))
-
- mux.Handle("/log_files", cr.apiAuthHandleFunc(cr.apiV0LogFiles))
- mux.Handle("/log_file/", cr.apiAuthHandle(http.StripPrefix("/log_file/", (http.HandlerFunc)(cr.apiV0LogFile))))
-
- next := cr.apiRateLimiter.WrapHandler(mux)
- return (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
- cr.authMiddleware(rw, req, next)
- })
-}
-
-func (cr *Cluster) initAPIv1() http.Handler {
- mux := http.NewServeMux()
- mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "404 not found",
- "path": req.URL.Path,
- })
- })
-
- mux.HandleFunc("/ping", cr.apiV1Ping)
-
- mux.HandleFunc("/challenge", cr.apiV1Challenge)
- mux.Handle("/logout", cr.apiAuthHandleFunc(cr.apiV1Logout))
-
- mux.HandleFunc("/log.io", cr.apiV1LogIO)
- mux.Handle("/pprof", cr.apiAuthHandleFunc(cr.apiV1Pprof))
-
- next := cr.apiRateLimiter.WrapHandler(mux)
- return (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
- cr.authMiddleware(rw, req, next)
- })
-}
-
-func (cr *Cluster) apiV1Ping(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- limited.SetSkipRateLimit(req)
- authed := getRequestTokenType(req) == tokenTypeAuth
- writeJson(rw, http.StatusOK, Map{
- "version": build.BuildVersion,
- "time": time.Now().UnixMilli(),
- "authed": authed,
- })
-}
-
-func (cr *Cluster) apiV0Status(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- limited.SetSkipRateLimit(req)
- type syncData struct {
- Prog int64 `json:"prog"`
- Total int64 `json:"total"`
- }
- type statusData struct {
- StartAt time.Time `json:"startAt"`
- Stats *notify.Stats `json:"stats"`
- Enabled bool `json:"enabled"`
- IsSync bool `json:"isSync"`
- Sync *syncData `json:"sync,omitempty"`
- Storages []string `json:"storages"`
- }
- storages := make([]string, len(cr.storageOpts))
- for i, opt := range cr.storageOpts {
- storages[i] = opt.Id
- }
- status := statusData{
- StartAt: startTime,
- Stats: &cr.stats,
- Enabled: cr.enabled.Load(),
- IsSync: cr.issync.Load(),
- Storages: storages,
- }
- if status.IsSync {
- status.Sync = &syncData{
- Prog: cr.syncProg.Load(),
- Total: cr.syncTotal.Load(),
- }
- }
- writeJson(rw, http.StatusOK, &status)
-}
-
-func (cr *Cluster) apiV0Stat(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- limited.SetSkipRateLimit(req)
- name := req.URL.Path
- if name == "" {
- rw.Header().Set("Cache-Control", "public, max-age=60")
- writeJson(rw, http.StatusOK, &cr.stats)
- return
- }
- data, err := cr.stats.MarshalSubStat(name)
- if err != nil {
- http.Error(rw, "Error when encoding response: "+err.Error(), http.StatusInternalServerError)
- return
- }
- rw.Header().Set("Cache-Control", "public, max-age=30")
- writeJson(rw, http.StatusOK, (json.RawMessage)(data))
-}
-
-func (cr *Cluster) apiV1Challenge(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- cli := apiGetClientId(req)
- query := req.URL.Query()
- action := query.Get("action")
- token, err := cr.generateChallengeToken(cli, action)
- if err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "Cannot generate token",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, Map{
- "token": token,
- })
-}
-
-func (cr *Cluster) apiV0Login(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodPost) {
- return
- }
- if !config.Dashboard.Enable {
- writeJson(rw, http.StatusServiceUnavailable, Map{
- "error": "dashboard is disabled in the config",
- })
- return
- }
- cli := apiGetClientId(req)
-
- type T = struct {
- User string `json:"username"`
- Challenge string `json:"challenge"`
- Signature string `json:"signature"`
- }
- data, ok := parseRequestBody(rw, req, func(rw http.ResponseWriter, req *http.Request, ct string, data *T) error {
- switch ct {
- case "application/x-www-form-urlencoded":
- data.User = req.PostFormValue("username")
- data.Challenge = req.PostFormValue("challenge")
- data.Signature = req.PostFormValue("signature")
- return nil
- default:
- return errUnknownContent
- }
- })
- if !ok {
- return
- }
-
- expectUsername, expectPassword := config.Dashboard.Username, config.Dashboard.Password
- if expectUsername == "" || expectPassword == "" {
- writeJson(rw, http.StatusUnauthorized, Map{
- "error": "The username or password was not set on the server",
- })
- return
- }
-
- if err := cr.verifyChallengeToken(cli, "login", data.Challenge); err != nil {
- writeJson(rw, http.StatusUnauthorized, Map{
- "error": "Invalid challenge",
- })
- return
- }
- expectPassword = utils.AsSha256Hex(expectPassword)
- expectSignature := utils.HMACSha256Hex(expectPassword, data.Challenge)
- if subtle.ConstantTimeCompare(([]byte)(expectUsername), ([]byte)(data.User)) == 0 ||
- subtle.ConstantTimeCompare(([]byte)(expectSignature), ([]byte)(data.Signature)) == 0 {
- writeJson(rw, http.StatusUnauthorized, Map{
- "error": "The username or password is incorrect",
- })
- return
- }
- token, err := cr.generateAuthToken(cli, data.User)
- if err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "Cannot generate token",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, Map{
- "token": token,
- })
-}
-
-func (cr *Cluster) apiV0RequestToken(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodPost) {
- return
- }
- defer req.Body.Close()
- if getRequestTokenType(req) != tokenTypeAuth {
- writeJson(rw, http.StatusUnauthorized, Map{
- "error": "invalid authorization type",
- })
- return
- }
-
- var payload struct {
- Path string `json:"path"`
- Query map[string]string `json:"query,omitempty"`
- }
- if err := json.NewDecoder(req.Body).Decode(&payload); err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "cannot decode payload in json format",
- "message": err.Error(),
- })
- }
- log.Debugf("payload: %#v", payload)
- if payload.Path == "" || payload.Path[0] != '/' {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "path is invalid",
- "message": "'path' must be a non empty string which starts with '/'",
- })
- return
- }
- cli := apiGetClientId(req)
- user := getLoggedUser(req)
- token, err := cr.generateAPIToken(cli, user, payload.Path, payload.Query)
- if err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "cannot generate token",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, Map{
- "token": token,
- })
-}
-
-func (cr *Cluster) apiV1Logout(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodPost) {
- return
- }
- limited.SetSkipRateLimit(req)
- tid := req.Context().Value(tokenIdKey).(string)
- cr.database.RemoveJTI(tid)
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV1LogIO(rw http.ResponseWriter, req *http.Request) {
- addr, _ := req.Context().Value(RealAddrCtxKey).(string)
-
- conn, err := cr.wsUpgrader.Upgrade(rw, req, nil)
- if err != nil {
- log.Debugf("[log.io]: Websocket upgrade error: %v", err)
- http.Error(rw, err.Error(), http.StatusInternalServerError)
- return
- }
- defer conn.Close()
-
- cli := apiGetClientId(req)
-
- ctx, cancel := context.WithCancel(req.Context())
- defer cancel()
-
- conn.SetReadLimit(1024 * 4)
- pongTimeoutTimer := time.NewTimer(time.Second * 75)
- go func() {
- defer conn.Close()
- defer cancel()
- defer pongTimeoutTimer.Stop()
- select {
- case _, ok := <-pongTimeoutTimer.C:
- if !ok {
- return
- }
- log.Error("[log.io]: Did not receive packet from client longer than 75s")
- return
- case <-ctx.Done():
- return
- }
- }()
-
- var authData struct {
- Token string `json:"token"`
- }
- deadline := time.Now().Add(time.Second * 10)
- conn.SetReadDeadline(deadline)
- err = conn.ReadJSON(&authData)
- conn.SetReadDeadline(time.Time{})
- if err != nil {
- if time.Now().After(deadline) {
- conn.WriteJSON(Map{
- "type": "error",
- "message": "auth timeout",
- })
- } else {
- conn.WriteJSON(Map{
- "type": "error",
- "message": "unexpected auth data: " + err.Error(),
- })
- }
- return
- }
- if _, _, err = cr.verifyAuthToken(cli, authData.Token); err != nil {
- conn.WriteJSON(Map{
- "type": "error",
- "message": "auth failed",
- })
- return
- }
- if err := conn.WriteJSON(Map{
- "type": "ready",
- }); err != nil {
- return
- }
-
- var level atomic.Int32
- level.Store((int32)(log.LevelInfo))
-
- type logObj struct {
- Type string `json:"type"`
- Time int64 `json:"time"` // UnixMilli
- Level string `json:"lvl"`
- Log string `json:"log"`
- }
- c := make(chan *logObj, 64)
- unregister := log.RegisterLogMonitor(log.LevelDebug, func(ts int64, l log.Level, msg string) {
- if (log.Level)(level.Load()) > l&log.LevelMask {
- return
- }
- select {
- case c <- &logObj{
- Type: "log",
- Time: ts,
- Level: l.String(),
- Log: msg,
- }:
- default:
- }
- })
- defer unregister()
-
- go func() {
- defer log.RecoverPanic(nil)
- defer conn.Close()
- defer cancel()
- var data map[string]any
- for {
- clear(data)
- if err := conn.ReadJSON(&data); err != nil {
- log.Errorf("[log.io]: Cannot read from peer: %v", err)
- return
- }
- typ, ok := data["type"].(string)
- if !ok {
- continue
- }
- switch typ {
- case "pong":
- log.Debugf("[log.io]: received PONG from %s: %v", addr, data["data"])
- pongTimeoutTimer.Reset(time.Second * 75)
- case "set-level":
- l, ok := data["level"].(string)
- if ok {
- switch l {
- case "DBUG":
- level.Store((int32)(log.LevelDebug))
- case "INFO":
- level.Store((int32)(log.LevelInfo))
- case "WARN":
- level.Store((int32)(log.LevelWarn))
- case "ERRO":
- level.Store((int32)(log.LevelError))
- default:
- continue
- }
- select {
- case c <- &logObj{
- Type: "log",
- Time: time.Now().UnixMilli(),
- Level: log.LevelInfo.String(),
- Log: "[dashboard]: Set log level to " + l + " for this log.io",
- }:
- default:
- }
- }
- }
- }
- }()
-
- sendMsgCh := make(chan any, 64)
- go func() {
- for {
- select {
- case v := <-c:
- select {
- case sendMsgCh <- v:
- case <-ctx.Done():
- return
- }
- case <-ctx.Done():
- return
- }
- }
- }()
-
- pingTicker := time.NewTicker(time.Second * 45)
- defer pingTicker.Stop()
- forceSendTimer := time.NewTimer(time.Second)
- if !forceSendTimer.Stop() {
- <-forceSendTimer.C
- }
-
- batchMsg := make([]any, 0, 64)
- for {
- select {
- case v := <-sendMsgCh:
- batchMsg = append(batchMsg, v)
- forceSendTimer.Reset(time.Second)
- WAIT_MORE:
- for {
- select {
- case v := <-sendMsgCh:
- batchMsg = append(batchMsg, v)
- case <-time.After(time.Millisecond * 20):
- if !forceSendTimer.Stop() {
- <-forceSendTimer.C
- }
- break WAIT_MORE
- case <-forceSendTimer.C:
- break WAIT_MORE
- case <-ctx.Done():
- forceSendTimer.Stop()
- return
- }
- }
- if len(batchMsg) == 1 {
- if err := conn.WriteJSON(batchMsg[0]); err != nil {
- return
- }
- } else {
- if err := conn.WriteJSON(batchMsg); err != nil {
- return
- }
- }
- // release objects
- for i, _ := range batchMsg {
- batchMsg[i] = nil
- }
- batchMsg = batchMsg[:0]
- case <-pingTicker.C:
- if err := conn.WriteJSON(Map{
- "type": "ping",
- "data": time.Now().UnixMilli(),
- }); err != nil {
- log.Errorf("[log.io]: Error when sending ping packet: %v", err)
- return
- }
- case <-ctx.Done():
- return
- }
- }
-}
-
-func (cr *Cluster) apiV1Pprof(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- query := req.URL.Query()
- lookup := query.Get("lookup")
- p := pprof.Lookup(lookup)
- if p == nil {
- http.Error(rw, fmt.Sprintf("pprof.Lookup(%q) returned nil", lookup), http.StatusBadRequest)
- return
- }
- view := query.Get("view")
- debug, err := strconv.Atoi(query.Get("debug"))
- if err != nil {
- debug = 1
- }
- if debug == 1 {
- rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
- } else {
- rw.Header().Set("Content-Type", "application/octet-stream")
- }
- if view != "1" {
- name := fmt.Sprintf(time.Now().Format("dump-%s-20060102-150405"), lookup)
- if debug == 1 {
- name += ".txt"
- } else {
- name += ".dump"
- }
- rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name))
- }
- rw.WriteHeader(http.StatusOK)
- if debug == 1 {
- fmt.Fprintf(rw, "version: %s (%s)\n", build.BuildVersion, build.ClusterVersion)
- }
- p.WriteTo(rw, debug)
-}
-
-func (cr *Cluster) apiV0SubscribeKey(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- key := cr.webpushKeyB64
- etag := `"` + utils.AsSha256(key) + `"`
- rw.Header().Set("ETag", etag)
- if cachedTag := req.Header.Get("If-None-Match"); cachedTag == etag {
- rw.WriteHeader(http.StatusNotModified)
- return
- }
- writeJson(rw, http.StatusOK, Map{
- "publicKey": key,
- })
-}
-
-func (cr *Cluster) apiV0Subscribe(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet, http.MethodPost, http.MethodDelete) {
- return
- }
- cliId := apiGetClientId(req)
- user := getLoggedUser(req)
- if user == "" {
- writeJson(rw, http.StatusForbidden, Map{
- "error": "Unauthorized",
- })
- return
- }
- switch req.Method {
- case http.MethodGet:
- cr.apiV0SubscribeGET(rw, req, user, cliId)
- case http.MethodPost:
- cr.apiV0SubscribePOST(rw, req, user, cliId)
- case http.MethodDelete:
- cr.apiV0SubscribeDELETE(rw, req, user, cliId)
- default:
- panic("unreachable")
- }
-}
-
-func (cr *Cluster) apiV0SubscribeGET(rw http.ResponseWriter, req *http.Request, user string, client string) {
- record, err := cr.database.GetSubscribe(user, client)
- if err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no subscription was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, Map{
- "scopes": record.Scopes,
- "reportAt": record.ReportAt,
- })
-}
-
-func (cr *Cluster) apiV0SubscribePOST(rw http.ResponseWriter, req *http.Request, user string, client string) {
- data, ok := parseRequestBody[database.SubscribeRecord](rw, req, nil)
- if !ok {
- return
- }
- data.User = user
- data.Client = client
- if err := cr.database.SetSubscribe(data); err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "Database update failed",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0SubscribeDELETE(rw http.ResponseWriter, req *http.Request, user string, client string) {
- if err := cr.database.RemoveSubscribe(user, client); err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no subscription was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0SubscribeEmail(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet, http.MethodPost, http.MethodPatch, http.MethodDelete) {
- return
- }
- user := getLoggedUser(req)
- if user == "" {
- writeJson(rw, http.StatusForbidden, Map{
- "error": "Unauthorized",
- })
- return
- }
- switch req.Method {
- case http.MethodGet:
- cr.apiV0SubscribeEmailGET(rw, req, user)
- case http.MethodPost:
- cr.apiV0SubscribeEmailPOST(rw, req, user)
- case http.MethodPatch:
- cr.apiV0SubscribeEmailPATCH(rw, req, user)
- case http.MethodDelete:
- cr.apiV0SubscribeEmailDELETE(rw, req, user)
- default:
- panic("unreachable")
- }
-}
-
-func (cr *Cluster) apiV0SubscribeEmailGET(rw http.ResponseWriter, req *http.Request, user string) {
- if addr := req.URL.Query().Get("addr"); addr != "" {
- record, err := cr.database.GetEmailSubscription(user, addr)
- if err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no email subscription was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, record)
- return
- }
- records := make([]database.EmailSubscriptionRecord, 0, 4)
- if err := cr.database.ForEachUsersEmailSubscription(user, func(rec *database.EmailSubscriptionRecord) error {
- records = append(records, *rec)
- return nil
- }); err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, records)
-}
-
-func (cr *Cluster) apiV0SubscribeEmailPOST(rw http.ResponseWriter, req *http.Request, user string) {
- data, ok := parseRequestBody[database.EmailSubscriptionRecord](rw, req, nil)
- if !ok {
- return
- }
-
- data.User = user
- if err := cr.database.AddEmailSubscription(data); err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "Database update failed",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusCreated)
-}
-
-func (cr *Cluster) apiV0SubscribeEmailPATCH(rw http.ResponseWriter, req *http.Request, user string) {
- addr := req.URL.Query().Get("addr")
- data, ok := parseRequestBody[database.EmailSubscriptionRecord](rw, req, nil)
- if !ok {
- return
- }
- data.User = user
- data.Addr = addr
- if err := cr.database.UpdateEmailSubscription(data); err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no email subscription was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0SubscribeEmailDELETE(rw http.ResponseWriter, req *http.Request, user string) {
- addr := req.URL.Query().Get("addr")
- if err := cr.database.RemoveEmailSubscription(user, addr); err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no email subscription was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0Webhook(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet, http.MethodPost, http.MethodPatch, http.MethodDelete) {
- return
- }
- user := getLoggedUser(req)
- if user == "" {
- writeJson(rw, http.StatusForbidden, Map{
- "error": "Unauthorized",
- })
- return
- }
- switch req.Method {
- case http.MethodGet:
- cr.apiV0WebhookGET(rw, req, user)
- case http.MethodPost:
- cr.apiV0WebhookPOST(rw, req, user)
- case http.MethodPatch:
- cr.apiV0WebhookPATCH(rw, req, user)
- case http.MethodDelete:
- cr.apiV0WebhookDELETE(rw, req, user)
- default:
- panic("unreachable")
- }
-}
-
-func (cr *Cluster) apiV0WebhookGET(rw http.ResponseWriter, req *http.Request, user string) {
- if sid := req.URL.Query().Get("id"); sid != "" {
- id, err := uuid.Parse(sid)
- if err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "uuid format error",
- "message": err.Error(),
- })
- return
- }
- record, err := cr.database.GetWebhook(user, id)
- if err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no webhook was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, record)
- return
- }
- records := make([]database.WebhookRecord, 0, 4)
- if err := cr.database.ForEachUsersWebhook(user, func(rec *database.WebhookRecord) error {
- records = append(records, *rec)
- return nil
- }); err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- writeJson(rw, http.StatusOK, records)
-}
-
-func (cr *Cluster) apiV0WebhookPOST(rw http.ResponseWriter, req *http.Request, user string) {
- data, ok := parseRequestBody[database.WebhookRecord](rw, req, nil)
- if !ok {
- return
- }
-
- data.User = user
- if err := cr.database.AddWebhook(data); err != nil {
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "Database update failed",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusCreated)
-}
-
-func (cr *Cluster) apiV0WebhookPATCH(rw http.ResponseWriter, req *http.Request, user string) {
- id := req.URL.Query().Get("id")
- data, ok := parseRequestBody[database.WebhookRecord](rw, req, nil)
- if !ok {
- return
- }
- data.User = user
- var err error
- if data.Id, err = uuid.Parse(id); err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "uuid format error",
- "message": err.Error(),
- })
- return
- }
- if err := cr.database.UpdateWebhook(data); err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no webhook was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0WebhookDELETE(rw http.ResponseWriter, req *http.Request, user string) {
- id, err := uuid.Parse(req.URL.Query().Get("id"))
- if err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "uuid format error",
- "message": err.Error(),
- })
- return
- }
- if err := cr.database.RemoveWebhook(user, id); err != nil {
- if err == database.ErrNotFound {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "no webhook was found",
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "database error",
- "message": err.Error(),
- })
- return
- }
- rw.WriteHeader(http.StatusNoContent)
-}
-
-func (cr *Cluster) apiV0LogFiles(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet) {
- return
- }
- files := log.ListLogs()
- type FileInfo struct {
- Name string `json:"name"`
- Size int64 `json:"size"`
- }
- data := make([]FileInfo, 0, len(files))
- for _, file := range files {
- if s, err := os.Stat(filepath.Join(log.BaseDir(), file)); err == nil {
- data = append(data, FileInfo{
- Name: file,
- Size: s.Size(),
- })
- }
- }
- writeJson(rw, http.StatusOK, Map{
- "files": data,
- })
-}
-
-func (cr *Cluster) apiV0LogFile(rw http.ResponseWriter, req *http.Request) {
- if checkRequestMethodOrRejectWithJson(rw, req, http.MethodGet, http.MethodHead) {
- return
- }
- query := req.URL.Query()
- fd, err := os.Open(filepath.Join(log.BaseDir(), req.URL.Path))
- if err != nil {
- if errors.Is(err, os.ErrNotExist) {
- writeJson(rw, http.StatusNotFound, Map{
- "error": "file not exists",
- "message": "Cannot find log file",
- "path": req.URL.Path,
- })
- return
- }
- writeJson(rw, http.StatusInternalServerError, Map{
- "error": "cannot open file",
- "message": err.Error(),
- })
- return
- }
- defer fd.Close()
- name := filepath.Base(req.URL.Path)
- isGzip := filepath.Ext(name) == ".gz"
- if query.Get("no_encrypt") == "1" {
- var modTime time.Time
- if stat, err := fd.Stat(); err == nil {
- modTime = stat.ModTime()
- }
- rw.Header().Set("Cache-Control", "public, max-age=60, stale-while-revalidate=600")
- if isGzip {
- rw.Header().Set("Content-Type", "application/octet-stream")
- } else {
- rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
- }
- rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name))
- http.ServeContent(rw, req, name, modTime, fd)
- } else {
- if !isGzip {
- name += ".gz"
- }
- rw.Header().Set("Content-Type", "application/octet-stream")
- rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name+".encrypted"))
- cr.apiV0LogFileEncrypted(rw, req, fd, !isGzip)
- }
-}
-
-func (cr *Cluster) apiV0LogFileEncrypted(rw http.ResponseWriter, req *http.Request, r io.Reader, useGzip bool) {
- rw.WriteHeader(http.StatusOK)
- if req.Method == http.MethodHead {
- return
- }
- if useGzip {
- pr, pw := io.Pipe()
- defer pr.Close()
- go func(r io.Reader) {
- gw := gzip.NewWriter(pw)
- if _, err := io.Copy(gw, r); err != nil {
- pw.CloseWithError(err)
- return
- }
- if err := gw.Close(); err != nil {
- pw.CloseWithError(err)
- return
- }
- pw.Close()
- }(r)
- r = pr
- }
- if err := utils.EncryptStream(rw, r, utils.DeveloporPublicKey); err != nil {
- log.Errorf("Cannot write encrypted log stream: %v", err)
- }
-}
-
-type Map = map[string]any
-
-var errUnknownContent = errors.New("unknown content-type")
-
-type requestBodyParser[T any] func(rw http.ResponseWriter, req *http.Request, contentType string, data *T) error
-
-func parseRequestBody[T any](rw http.ResponseWriter, req *http.Request, fallback requestBodyParser[T]) (data T, parsed bool) {
- contentType, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
- if err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "Unexpected Content-Type",
- "content-type": req.Header.Get("Content-Type"),
- "message": err.Error(),
- })
- return
- }
- switch contentType {
- case "application/json":
- if err := json.NewDecoder(req.Body).Decode(&data); err != nil {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "Cannot decode request body",
- "message": err.Error(),
- })
- return
- }
- return data, true
- default:
- if fallback != nil {
- if err := fallback(rw, req, contentType, &data); err == nil {
- return data, true
- } else if err != errUnknownContent {
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "Cannot decode request body",
- "message": err.Error(),
- })
- return
- }
- }
- writeJson(rw, http.StatusBadRequest, Map{
- "error": "Unexpected Content-Type",
- "content-type": contentType,
- })
- return
- }
-}
-
-func writeJson(rw http.ResponseWriter, code int, data any) (err error) {
- buf, err := json.Marshal(data)
- if err != nil {
- http.Error(rw, "Error when encoding response: "+err.Error(), http.StatusInternalServerError)
- return
- }
- rw.Header().Set("Content-Type", "application/json")
- rw.Header().Set("Content-Length", strconv.Itoa(len(buf)))
- rw.WriteHeader(code)
- _, err = rw.Write(buf)
- return
-}
-
-func checkRequestMethodOrRejectWithJson(rw http.ResponseWriter, req *http.Request, allows ...string) (rejected bool) {
- m := req.Method
- for _, a := range allows {
- if m == a {
- return false
- }
- }
- rw.Header().Set("Allow", strings.Join(allows, ", "))
- writeJson(rw, http.StatusMethodNotAllowed, Map{
- "error": "405 method not allowed",
- "method": m,
- "allow": allows,
- })
- return true
-}
diff --git a/hijacker.go b/api/bmclapi/hijacker.go
similarity index 87%
rename from hijacker.go
rename to api/bmclapi/hijacker.go
index 6cc78049..3218c2b0 100644
--- a/hijacker.go
+++ b/api/bmclapi/hijacker.go
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package main
+package bmclapi
import (
"context"
@@ -33,6 +33,7 @@ import (
"sync"
"time"
+ "github.com/LiterMC/go-openbmclapi/config"
"github.com/LiterMC/go-openbmclapi/database"
"github.com/LiterMC/go-openbmclapi/utils"
)
@@ -52,6 +53,11 @@ func getDialerWithDNS(dnsaddr string) *net.Dialer {
type downloadHandlerFn = func(rw http.ResponseWriter, req *http.Request, hash string)
type HjProxy struct {
+ RequireAuth bool
+ AuthUsers []config.UserItem
+ EnableLocalCache bool
+ LocalCachePath string
+
client *http.Client
fileMap database.DB
downloadHandler downloadHandlerFn
@@ -76,11 +82,11 @@ func NewHjProxy(client *http.Client, fileMap database.DB, downloadHandler downlo
return
}
-func hjResponseWithCache(rw http.ResponseWriter, req *http.Request, c *cacheStat, force bool) (ok bool) {
+func (h *HjProxy) hjResponseWithCache(rw http.ResponseWriter, req *http.Request, c *cacheStat, force bool) (ok bool) {
if c == nil {
return false
}
- cacheFileName := filepath.Join(config.Hijack.LocalCachePath, filepath.FromSlash(req.URL.Path))
+ cacheFileName := filepath.Join(h.LocalCachePath, filepath.FromSlash(req.URL.Path))
age := c.ExpiresAt - time.Now().Unix()
if !force && age <= 0 {
return false
@@ -107,15 +113,11 @@ func hjResponseWithCache(rw http.ResponseWriter, req *http.Request, c *cacheStat
const hijackingHost = "bmclapi2.bangbang93.com"
func (h *HjProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
- if !config.Hijack.Enable {
- http.Error(rw, "Hijack is disabled in the config", http.StatusServiceUnavailable)
- return
- }
- if config.Hijack.RequireAuth {
+ if h.RequireAuth {
needAuth := true
user, passwd, ok := req.BasicAuth()
if ok {
- for _, u := range config.Hijack.AuthUsers {
+ for _, u := range h.AuthUsers {
if u.Username == user && utils.ComparePasswd(u.Password, passwd) {
needAuth = false
return
@@ -139,9 +141,9 @@ func (h *HjProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
nowUnix := time.Now().Unix()
- cacheFileName := filepath.Join(config.Hijack.LocalCachePath, filepath.FromSlash(req.URL.Path))
+ cacheFileName := filepath.Join(h.LocalCachePath, filepath.FromSlash(req.URL.Path))
cached := h.getCache(req.URL.Path)
- if hjResponseWithCache(rw, req, cached, false) {
+ if h.hjResponseWithCache(rw, req, cached, false) {
return
}
@@ -158,7 +160,7 @@ func (h *HjProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
res, err := h.client.Do(req2)
if err != nil {
- if hjResponseWithCache(rw, req, cached, true) {
+ if h.hjResponseWithCache(rw, req, cached, true) {
return
}
http.Error(rw, "remote: "+err.Error(), http.StatusBadGateway)
@@ -178,7 +180,7 @@ func (h *HjProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
rw.WriteHeader(res.StatusCode)
var body io.Reader = res.Body
- if config.Hijack.EnableLocalCache && res.StatusCode == http.StatusOK {
+ if h.EnableLocalCache && res.StatusCode == http.StatusOK {
if exp, ok := utils.ParseCacheControl(res.Header.Get("Cache-Control")); ok {
if exp > 0 {
os.MkdirAll(filepath.Dir(cacheFileName), 0755)
@@ -211,7 +213,7 @@ type cacheStat struct {
func (h *HjProxy) loadCache() (err error) {
h.cache = make(map[string]*cacheStat)
- fd, err := os.Open(filepath.Join(config.Hijack.LocalCachePath, "__cache.json"))
+ fd, err := os.Open(filepath.Join(h.LocalCachePath, "__cache.json"))
if err != nil {
return
}
@@ -220,7 +222,7 @@ func (h *HjProxy) loadCache() (err error) {
}
func (h *HjProxy) saveCache() (err error) {
- fd, err := os.Create(filepath.Join(config.Hijack.LocalCachePath, "__cache.json"))
+ fd, err := os.Create(filepath.Join(h.LocalCachePath, "__cache.json"))
if err != nil {
return
}
diff --git a/api/cluster.go b/api/cluster.go
new file mode 100644
index 00000000..31cd7a87
--- /dev/null
+++ b/api/cluster.go
@@ -0,0 +1,98 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "context"
+ "net/http"
+
+ "github.com/LiterMC/go-openbmclapi/config"
+ "github.com/LiterMC/go-openbmclapi/storage"
+)
+
+type ClusterStatus int32
+
+const (
+ ClusterDisconnected = iota
+ ClusterConnecting
+ ClusterDisabled
+ ClusterEnabling
+ ClusterEnabled
+)
+
+// Disconnected returns true if the cluster is disconnected from the central server
+func (s ClusterStatus) Disconnected() bool {
+ return s <= ClusterConnecting
+}
+
+// Connected returns true if the cluster is connected to the central server
+func (s ClusterStatus) Connected() bool {
+ return s > ClusterConnecting
+}
+
+// Enabled returns true if the cluster is enabled or enabling
+func (s ClusterStatus) Enabled() bool {
+ return s >= ClusterEnabling
+}
+
+// Running returns true if the cluster is completely enabled
+func (s ClusterStatus) Running() bool {
+ return s == ClusterEnabled
+}
+
+type Cluster interface {
+ Name() string
+ ID() string
+ Secret() string
+ Host() string
+ Port() uint16
+ PublicHosts() []string
+ Options() *config.ClusterOptions
+
+ Status() ClusterStatus
+ Connect(context.Context) error
+ Disconnect(context.Context) error
+ Enable(context.Context) error
+ Disable(context.Context) error
+
+ GetFileList(ctx context.Context, fileMap map[string]*StorageFileInfo, forceAll bool) error
+ ReportDownload(ctx context.Context, response *http.Response, err error) error
+}
+
+type StorageFileInfo struct {
+ Hash string
+ Size int64
+ Storages []storage.Storage
+ URLs map[string]RequestPath
+}
+
+type RequestPath struct {
+ *http.Request
+ Cluster Cluster
+ Path string
+}
+
+type ClusterManager interface {
+ GetClusters() []Cluster
+ GetCluster(name string) Cluster
+ AddCluster(name string, opts *config.ClusterOptions) error
+ UpdateCluster(name string, opts *config.ClusterOptions) error
+ RemoveCluster(name string) bool
+}
diff --git a/api/config.go b/api/config.go
new file mode 100644
index 00000000..8d99aa3c
--- /dev/null
+++ b/api/config.go
@@ -0,0 +1,41 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "errors"
+
+ "github.com/LiterMC/go-openbmclapi/config"
+)
+
+var ErrPreconditionFailed = errors.New("Precondition Failed")
+
+type ConfigHandler interface {
+ GetConfig() *config.Config
+
+ MarshalJSON() (data []byte, err error)
+ UnmarshalJSON(data []byte) error
+ UnmarshalYAML(data []byte) error
+ MarshalJSONPath(path string) (data []byte, err error)
+ UnmarshalJSONPath(path string, data []byte) error
+
+ DoReadLockedAction(callback func(ConfigHandler) error) error
+ DoWriteLockedAction(callback func(ConfigHandler) error) error
+}
diff --git a/exitcodes.go b/api/errors.go
similarity index 62%
rename from exitcodes.go
rename to api/errors.go
index 9d540825..3b0214d9 100644
--- a/exitcodes.go
+++ b/api/errors.go
@@ -17,19 +17,14 @@
* along with this program. If not, see .
*/
-package main
+package api
-const (
- CodeClientError = 0x01
- CodeServerError = 0x02
- CodeEnvironmentError = 0x04
- CodeUnexpectedError = 0x08
+import (
+ "errors"
)
-const (
- CodeClientOrServerError = CodeClientError | CodeServerError
- CodeClientOrEnvionmentError = CodeClientError | CodeEnvironmentError
- CodeClientUnexpectedError = CodeUnexpectedError | CodeClientError
- CodeServerOrEnvionmentError = CodeServerError | CodeEnvironmentError
- CodeServerUnexpectedError = CodeUnexpectedError | CodeServerError
+var (
+ ErrStopIter = errors.New("stop iteration")
+ ErrNotFound = errors.New("Item not found")
+ ErrExist = errors.New("Item is already exist")
)
diff --git a/api/request.go b/api/request.go
new file mode 100644
index 00000000..74588c34
--- /dev/null
+++ b/api/request.go
@@ -0,0 +1,45 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "net/http"
+)
+
+const (
+ RealAddrCtxKey = "handle.real.addr"
+ RealPathCtxKey = "handle.real.path"
+ AccessLogExtraCtxKey = "handle.access.extra"
+)
+
+func GetRequestRealAddr(req *http.Request) string {
+ addr, _ := req.Context().Value(RealAddrCtxKey).(string)
+ return addr
+}
+
+func GetRequestRealPath(req *http.Request) string {
+ return req.Context().Value(RealPathCtxKey).(string)
+}
+
+func SetAccessInfo(req *http.Request, key string, value any) {
+ if info, ok := req.Context().Value(AccessLogExtraCtxKey).(map[string]any); ok {
+ info[key] = value
+ }
+}
diff --git a/api/stats.go b/api/stats.go
new file mode 100644
index 00000000..f0cbaeeb
--- /dev/null
+++ b/api/stats.go
@@ -0,0 +1,233 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "strconv"
+ "time"
+)
+
+type StatsManager interface {
+ GetStatus() StatusData
+ // returns a cluster's stat data
+ // if name is empty then gets the overall access data
+ GetClusterAccessStat(name string) *AccessStatData
+ // returns a storage's stat data
+ // if name is empty then gets the overall access data
+ GetStorageAccessStat(name string) *AccessStatData
+}
+
+type StatusData struct {
+ StartAt time.Time `json:"startAt"`
+ Clusters []string `json:"clusters"`
+ Storages []string `json:"storages"`
+}
+
+type StatInstData struct {
+ Hits int32 `json:"hits"`
+ Bytes int64 `json:"bytes"`
+}
+
+func (d *StatInstData) update(o *StatInstData) {
+ d.Hits += o.Hits
+ d.Bytes += o.Bytes
+}
+
+// statTime always save a UTC time
+type statTime struct {
+ Hour int `json:"hour"`
+ Day int `json:"day"`
+ Month int `json:"month"`
+ Year int `json:"year"`
+}
+
+func makeStatTime(t time.Time) (st statTime) {
+ t = t.UTC()
+ st.Hour = t.Hour()
+ y, m, d := t.Date()
+ st.Day = d - 1
+ st.Month = (int)(m) - 1
+ st.Year = y
+ return
+}
+
+func (t statTime) IsLastDay() bool {
+ return time.Date(t.Year, (time.Month)(t.Month+1), t.Day+1+1, 0, 0, 0, 0, time.UTC).Day() == 1
+}
+
+type (
+ StatDataHours = [24]StatInstData
+ StatDataDays = [31]StatInstData
+ StatDataMonths = [12]StatInstData
+)
+
+type AccessStatHistoryData struct {
+ Hours StatDataHours `json:"hours"`
+ Days StatDataDays `json:"days"`
+ Months StatDataMonths `json:"months"`
+}
+
+type AccessStatData struct {
+ Date statTime `json:"date"`
+ AccessStatHistoryData
+ Prev AccessStatHistoryData `json:"prev"`
+ Years map[string]StatInstData `json:"years"`
+
+ Accesses map[string]int `json:"accesses"`
+}
+
+func NewAccessStatData() *AccessStatData {
+ return &AccessStatData{
+ Years: make(map[string]StatInstData, 2),
+ Accesses: make(map[string]int, 5),
+ }
+}
+
+func (d *AccessStatData) Clone() *AccessStatData {
+ cloned := new(AccessStatData)
+ *cloned = *d
+ cloned.Years = make(map[string]StatInstData, len(d.Years))
+ for k, v := range d.Years {
+ cloned.Years[k] = v
+ }
+ cloned.Accesses = make(map[string]int, len(d.Accesses))
+ for k, v := range d.Accesses {
+ cloned.Accesses[k] = v
+ }
+ return cloned
+}
+
+func (d *AccessStatData) Update(newData *StatInstData) {
+ now := makeStatTime(time.Now())
+ if d.Date.Year != 0 {
+ switch {
+ case d.Date.Year != now.Year:
+ iscont := now.Year == d.Date.Year+1
+ isMonthCont := iscont && now.Month == 0 && d.Date.Month+1 == len(d.Months)
+ var inst StatInstData
+ for i := 0; i < d.Date.Month; i++ {
+ inst.update(&d.Months[i])
+ }
+ if iscont {
+ for i := 0; i <= d.Date.Day; i++ {
+ inst.update(&d.Days[i])
+ }
+ if isMonthCont {
+ for i := 0; i <= d.Date.Hour; i++ {
+ inst.update(&d.Hours[i])
+ }
+ }
+ }
+ d.Years[strconv.Itoa(d.Date.Year)] = inst
+ // update history data
+ if iscont {
+ if isMonthCont {
+ if now.Day == 0 && d.Date.IsLastDay() {
+ d.Prev.Hours = d.Hours
+ for i := d.Date.Hour + 1; i < len(d.Hours); i++ {
+ d.Prev.Hours[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Hours = StatDataHours{}
+ }
+ d.Hours = StatDataHours{}
+ d.Prev.Days = d.Days
+ for i := d.Date.Day + 1; i < len(d.Days); i++ {
+ d.Prev.Days[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Days = StatDataDays{}
+ }
+ d.Days = StatDataDays{}
+ d.Prev.Months = d.Months
+ for i := d.Date.Month + 1; i < len(d.Months); i++ {
+ d.Prev.Months[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Months = StatDataMonths{}
+ }
+ d.Months = StatDataMonths{}
+ case d.Date.Month != now.Month:
+ iscont := now.Month == d.Date.Month+1
+ var inst StatInstData
+ for i := 0; i < d.Date.Day; i++ {
+ inst.update(&d.Days[i])
+ }
+ if iscont {
+ for i := 0; i <= d.Date.Hour; i++ {
+ inst.update(&d.Hours[i])
+ }
+ }
+ d.Months[d.Date.Month] = inst
+ // clean up
+ for i := d.Date.Month + 1; i < now.Month; i++ {
+ d.Months[i] = StatInstData{}
+ }
+ clear(d.Accesses)
+ // update history data
+ if iscont {
+ if now.Day == 0 && d.Date.IsLastDay() {
+ d.Prev.Hours = d.Hours
+ for i := d.Date.Hour + 1; i < len(d.Hours); i++ {
+ d.Prev.Hours[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Hours = StatDataHours{}
+ }
+ d.Hours = StatDataHours{}
+ d.Prev.Days = d.Days
+ for i := d.Date.Day + 1; i < len(d.Days); i++ {
+ d.Prev.Days[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Days = StatDataDays{}
+ }
+ d.Days = StatDataDays{}
+ case d.Date.Day != now.Day:
+ var inst StatInstData
+ for i := 0; i <= d.Date.Hour; i++ {
+ inst.update(&d.Hours[i])
+ }
+ d.Days[d.Date.Day] = inst
+ // clean up
+ for i := d.Date.Day + 1; i < now.Day; i++ {
+ d.Days[i] = StatInstData{}
+ }
+ // update history data
+ if now.Day == d.Date.Day+1 {
+ d.Prev.Hours = d.Hours
+ for i := d.Date.Hour + 1; i < len(d.Hours); i++ {
+ d.Prev.Hours[i] = StatInstData{}
+ }
+ } else {
+ d.Prev.Hours = StatDataHours{}
+ }
+ d.Hours = StatDataHours{}
+ case d.Date.Hour != now.Hour:
+ // clean up
+ for i := d.Date.Hour + 1; i < now.Hour; i++ {
+ d.Hours[i] = StatInstData{}
+ }
+ }
+ }
+
+ d.Hours[now.Hour].update(newData)
+ d.Date = now
+}
diff --git a/api/subscription.go b/api/subscription.go
new file mode 100644
index 00000000..2749c895
--- /dev/null
+++ b/api/subscription.go
@@ -0,0 +1,300 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type SubscriptionManager interface {
+ GetWebPushKey() string
+
+ GetSubscribe(user string, client string) (*SubscribeRecord, error)
+ SetSubscribe(SubscribeRecord) error
+ RemoveSubscribe(user string, client string) error
+ ForEachSubscribe(cb func(*SubscribeRecord) error) error
+
+ GetEmailSubscription(user string, addr string) (*EmailSubscriptionRecord, error)
+ AddEmailSubscription(EmailSubscriptionRecord) error
+ UpdateEmailSubscription(EmailSubscriptionRecord) error
+ RemoveEmailSubscription(user string, addr string) error
+ ForEachEmailSubscription(cb func(*EmailSubscriptionRecord) error) error
+ ForEachUsersEmailSubscription(user string, cb func(*EmailSubscriptionRecord) error) error
+ ForEachEnabledEmailSubscription(cb func(*EmailSubscriptionRecord) error) error
+
+ GetWebhook(user string, id uuid.UUID) (*WebhookRecord, error)
+ AddWebhook(WebhookRecord) error
+ UpdateWebhook(WebhookRecord) error
+ UpdateEnableWebhook(user string, id uuid.UUID, enabled bool) error
+ RemoveWebhook(user string, id uuid.UUID) error
+ ForEachWebhook(cb func(*WebhookRecord) error) error
+ ForEachUsersWebhook(user string, cb func(*WebhookRecord) error) error
+ ForEachEnabledWebhook(cb func(*WebhookRecord) error) error
+}
+
+type SubscribeRecord struct {
+ User string `json:"user"`
+ Client string `json:"client"`
+ EndPoint string `json:"endpoint"`
+ Keys SubscribeRecordKeys `json:"keys"`
+ Scopes NotificationScopes `json:"scopes"`
+ ReportAt Schedule `json:"report_at"`
+ LastReport sql.NullTime `json:"-"`
+}
+
+type SubscribeRecordKeys struct {
+ Auth string `json:"auth"`
+ P256dh string `json:"p256dh"`
+}
+
+var (
+ _ sql.Scanner = (*SubscribeRecordKeys)(nil)
+ _ driver.Valuer = (*SubscribeRecordKeys)(nil)
+)
+
+func (sk *SubscribeRecordKeys) Scan(src any) error {
+ var data []byte
+ switch v := src.(type) {
+ case []byte:
+ data = v
+ case string:
+ data = ([]byte)(v)
+ default:
+ return errors.New("Source is not a string")
+ }
+ return json.Unmarshal(data, sk)
+}
+
+func (sk SubscribeRecordKeys) Value() (driver.Value, error) {
+ return json.Marshal(sk)
+}
+
+type NotificationScopes struct {
+ Disabled bool `json:"disabled"`
+ Enabled bool `json:"enabled"`
+ SyncBegin bool `json:"syncbegin"`
+ SyncDone bool `json:"syncdone"`
+ Updates bool `json:"updates"`
+ DailyReport bool `json:"dailyreport"`
+}
+
+var (
+ _ sql.Scanner = (*NotificationScopes)(nil)
+ _ driver.Valuer = (*NotificationScopes)(nil)
+)
+
+//// !!WARN: Do not edit nsFlag's order ////
+
+const (
+ nsFlagDisabled = 1 << iota
+ nsFlagEnabled
+ nsFlagSyncDone
+ nsFlagUpdates
+ nsFlagDailyReport
+ nsFlagSyncBegin
+)
+
+func (ns NotificationScopes) ToInt64() (v int64) {
+ if ns.Disabled {
+ v |= nsFlagDisabled
+ }
+ if ns.Enabled {
+ v |= nsFlagEnabled
+ }
+ if ns.SyncBegin {
+ v |= nsFlagSyncBegin
+ }
+ if ns.SyncDone {
+ v |= nsFlagSyncDone
+ }
+ if ns.Updates {
+ v |= nsFlagUpdates
+ }
+ if ns.DailyReport {
+ v |= nsFlagDailyReport
+ }
+ return
+}
+
+func (ns *NotificationScopes) FromInt64(v int64) {
+ ns.Disabled = v&nsFlagDisabled != 0
+ ns.Enabled = v&nsFlagEnabled != 0
+ ns.SyncBegin = v&nsFlagSyncBegin != 0
+ ns.SyncDone = v&nsFlagSyncDone != 0
+ ns.Updates = v&nsFlagUpdates != 0
+ ns.DailyReport = v&nsFlagDailyReport != 0
+}
+
+func (ns *NotificationScopes) Scan(src any) error {
+ v, ok := src.(int64)
+ if !ok {
+ return errors.New("Source is not a integer")
+ }
+ ns.FromInt64(v)
+ return nil
+}
+
+func (ns NotificationScopes) Value() (driver.Value, error) {
+ return ns.ToInt64(), nil
+}
+
+func (ns *NotificationScopes) FromStrings(scopes []string) {
+ for _, s := range scopes {
+ switch s {
+ case "disabled":
+ ns.Disabled = true
+ case "enabled":
+ ns.Enabled = true
+ case "syncbegin":
+ ns.SyncBegin = true
+ case "syncdone":
+ ns.SyncDone = true
+ case "updates":
+ ns.Updates = true
+ case "dailyreport":
+ ns.DailyReport = true
+ }
+ }
+}
+
+func (ns *NotificationScopes) UnmarshalJSON(data []byte) (err error) {
+ {
+ type T NotificationScopes
+ if err = json.Unmarshal(data, (*T)(ns)); err == nil {
+ return
+ }
+ }
+ var v []string
+ if err = json.Unmarshal(data, &v); err != nil {
+ return
+ }
+ ns.FromStrings(v)
+ return
+}
+
+type Schedule struct {
+ Hour int
+ Minute int
+}
+
+var (
+ _ sql.Scanner = (*Schedule)(nil)
+ _ driver.Valuer = (*Schedule)(nil)
+)
+
+func (s Schedule) String() string {
+ return fmt.Sprintf("%02d:%02d", s.Hour, s.Minute)
+}
+
+func (s *Schedule) UnmarshalText(buf []byte) (err error) {
+ if _, err = fmt.Sscanf((string)(buf), "%02d:%02d", &s.Hour, &s.Minute); err != nil {
+ return
+ }
+ if s.Hour < 0 || s.Hour >= 24 {
+ return fmt.Errorf("Hour %d out of range [0, 24)", s.Hour)
+ }
+ if s.Minute < 0 || s.Minute >= 60 {
+ return fmt.Errorf("Minute %d out of range [0, 60)", s.Minute)
+ }
+ return
+}
+
+func (s *Schedule) UnmarshalJSON(buf []byte) (err error) {
+ var v string
+ if err = json.Unmarshal(buf, &v); err != nil {
+ return
+ }
+ return s.UnmarshalText(([]byte)(v))
+}
+
+func (s *Schedule) MarshalJSON() (buf []byte, err error) {
+ return json.Marshal(s.String())
+}
+
+func (s *Schedule) Scan(src any) error {
+ var v []byte
+ switch w := src.(type) {
+ case []byte:
+ v = w
+ case string:
+ v = ([]byte)(w)
+ default:
+ return fmt.Errorf("Unexpected type %T", src)
+ }
+ return s.UnmarshalText(v)
+}
+
+func (s Schedule) Value() (driver.Value, error) {
+ return s.String(), nil
+}
+
+func (s Schedule) ReadySince(last, now time.Time) bool {
+ if last.IsZero() {
+ last = now.Add(-time.Hour*24 + 1)
+ }
+ mustAfter := last.Add(time.Hour * 12)
+ if now.Before(mustAfter) {
+ return false
+ }
+ if !now.Before(last.Add(time.Hour * 24)) {
+ return true
+ }
+ hour, min := now.Hour(), now.Minute()
+ if s.Hour < hour && s.Hour+3 > hour || s.Hour == hour && s.Minute <= min {
+ return true
+ }
+ return false
+}
+
+type EmailSubscriptionRecord struct {
+ User string `json:"user"`
+ Addr string `json:"addr"`
+ Scopes NotificationScopes `json:"scopes"`
+ Enabled bool `json:"enabled"`
+}
+
+type WebhookRecord struct {
+ User string `json:"user"`
+ Id uuid.UUID `json:"id"`
+ Name string `json:"name"`
+ EndPoint string `json:"endpoint"`
+ Auth *string `json:"auth,omitempty"`
+ AuthHash string `json:"authHash,omitempty"`
+ Scopes NotificationScopes `json:"scopes"`
+ Enabled bool `json:"enabled"`
+}
+
+func (rec *WebhookRecord) CovertAuthHash() {
+ if rec.Auth == nil || *rec.Auth == "" {
+ rec.AuthHash = ""
+ } else {
+ rec.AuthHash = "sha256:" + utils.AsSha256Hex(*rec.Auth)
+ }
+ rec.Auth = nil
+}
diff --git a/database/db_test.go b/api/subscription_test.go
similarity index 97%
rename from database/db_test.go
rename to api/subscription_test.go
index 4300f23d..146505a8 100644
--- a/database/db_test.go
+++ b/api/subscription_test.go
@@ -17,13 +17,13 @@
* along with this program. If not, see .
*/
-package database_test
+package api_test
import (
"encoding/json"
"time"
- . "github.com/LiterMC/go-openbmclapi/database"
+ . "github.com/LiterMC/go-openbmclapi/api"
"testing"
)
diff --git a/api/token.go b/api/token.go
new file mode 100644
index 00000000..8dfcbdc9
--- /dev/null
+++ b/api/token.go
@@ -0,0 +1,38 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+import (
+ "net/url"
+)
+
+type TokenVerifier interface {
+ VerifyChallengeToken(clientId string, token string, action string) (err error)
+ VerifyAuthToken(clientId string, token string) (tokenId string, userId string, err error)
+ VerifyAPIToken(clientId string, token string, path string, query url.Values) (userId string, err error)
+}
+
+type TokenManager interface {
+ TokenVerifier
+ GenerateChallengeToken(clientId string, action string) (token string, err error)
+ GenerateAuthToken(clientId string, userId string) (token string, err error)
+ GenerateAPIToken(clientId string, userId string, path string, query map[string]string) (token string, err error)
+ InvalidToken(tokenId string) error
+}
diff --git a/api/user.go b/api/user.go
new file mode 100644
index 00000000..5d22fad3
--- /dev/null
+++ b/api/user.go
@@ -0,0 +1,67 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package api
+
+type UserManager interface {
+ GetUsers() []*User
+ GetUser(id string) *User
+ AddUser(*User) error
+ RemoveUser(id string) error
+ ForEachUser(cb func(*User) error) error
+ UpdateUserPassword(username string, password string) error
+ UpdateUserPermissions(username string, permissions PermissionFlag) error
+
+ VerifyUserPassword(userId string, comparator func(password string) bool) error
+}
+
+type PermissionFlag uint32
+
+const (
+ // BasicPerm includes majority client side actions, such as login, which do not have a significant impact on the server
+ BasicPerm PermissionFlag = 1 << iota
+ // SubscribePerm allows the user to subscribe server status & other posts
+ SubscribePerm
+ // LogPerm allows the user to view non-debug logs & download access logs
+ LogPerm
+ // DebugPerm allows the user to access debug settings & download debug logs
+ DebugPerm
+ // FullConfigPerm allows the user to access all config values
+ FullConfigPerm
+ // ClusterPerm allows the user to configure clusters' settings & stop/start clusters
+ ClusterPerm
+ // StoragePerm allows the user to configure storages' settings & decides to manually start storages' sync process
+ StoragePerm
+ // BypassLimitPerm allows the user to ignore API access limit
+ BypassLimitPerm
+ // RootPerm user can add/remove users, reset their password, and change their permission flags
+ RootPerm PermissionFlag = 1 << 31
+
+ AllPerm = ^(PermissionFlag)(0)
+)
+
+type User struct {
+ Username string
+ Password string // as sha256
+ Permissions PermissionFlag
+}
+
+func (u *User) HasPerm(perm PermissionFlag) bool {
+ return u.Permissions&perm == perm
+}
diff --git a/api/v0/api.go b/api/v0/api.go
new file mode 100644
index 00000000..42129980
--- /dev/null
+++ b/api/v0/api.go
@@ -0,0 +1,172 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2023 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "encoding/json"
+ "errors"
+ "mime"
+ "net/http"
+ "strconv"
+
+ "github.com/gorilla/schema"
+ "github.com/gorilla/websocket"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type Handler struct {
+ handler *utils.HttpMiddleWareHandler
+ router *http.ServeMux
+ wsUpgrader *websocket.Upgrader
+ config api.ConfigHandler
+ clusters api.ClusterManager
+ users api.UserManager
+ tokens api.TokenManager
+ subscriptions api.SubscriptionManager
+ stats api.StatsManager
+}
+
+var _ http.Handler = (*Handler)(nil)
+
+func NewHandler(
+ wsUpgrader *websocket.Upgrader,
+ config api.ConfigHandler,
+ clusters api.ClusterManager,
+ users api.UserManager,
+ tokenManager api.TokenManager,
+ subManager api.SubscriptionManager,
+ statsManager api.StatsManager,
+) *Handler {
+ mux := http.NewServeMux()
+ h := &Handler{
+ router: mux,
+ handler: utils.NewHttpMiddleWareHandler(mux),
+ wsUpgrader: wsUpgrader,
+ config: config,
+ clusters: clusters,
+ users: users,
+ tokens: tokenManager,
+ subscriptions: subManager,
+ stats: statsManager,
+ }
+ h.buildRoute()
+ h.handler.UseFunc(cliIdMiddleWare, h.authMiddleWare)
+ return h
+}
+
+func (h *Handler) Handler() *utils.HttpMiddleWareHandler {
+ return h.handler
+}
+
+func (h *Handler) buildRoute() {
+ mux := h.router
+
+ mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "404 not found",
+ "path": req.URL.Path,
+ })
+ })
+
+ h.buildAuthRoute(mux)
+ h.buildClusterRoute(mux)
+ h.buildConfigureRoute(mux)
+ h.buildDebugRoute(mux)
+ h.buildStatRoute(mux)
+ h.buildSubscriptionRoute(mux)
+}
+
+func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ h.handler.ServeHTTP(rw, req)
+}
+
+type Map = map[string]any
+
+var errUnknownContent = errors.New("unknown content-type")
+var formDecoder = schema.NewDecoder()
+
+func parseRequestBody(rw http.ResponseWriter, req *http.Request, ptr any) (parsed bool) {
+ contentType, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": err.Error(),
+ })
+ return
+ }
+ switch contentType {
+ case "application/json":
+ if err := json.NewDecoder(req.Body).Decode(ptr); err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Cannot decode request body",
+ "message": err.Error(),
+ })
+ return
+ }
+ return true
+ case "application/x-www-form-urlencoded":
+ if err := req.ParseForm(); err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Cannot decode request body",
+ "message": err.Error(),
+ })
+ return
+ }
+ if err := formDecoder.Decode(ptr, req.PostForm); err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Cannot decode request body",
+ "message": err.Error(),
+ })
+ return
+ }
+ return true
+ default:
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": contentType,
+ })
+ return
+ }
+}
+
+func calcSha256ETag(data []byte) string {
+ return `"sha256:` + utils.BytesAsSha256(data) + `"`
+}
+
+func writeJson(rw http.ResponseWriter, code int, data any) (err error) {
+ buf, err := json.Marshal(data)
+ if err != nil {
+ http.Error(rw, "Error when encoding response: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+ rw.Header().Set("Content-Type", "application/json")
+ rw.Header().Set("Content-Length", strconv.Itoa(len(buf)))
+ rw.WriteHeader(code)
+ _, err = rw.Write(buf)
+ return
+}
+
+func errorMethodNotAllowed(rw http.ResponseWriter, req *http.Request, allow string) {
+ rw.Header().Set("Allow", allow)
+ rw.WriteHeader(http.StatusMethodNotAllowed)
+}
diff --git a/api/v0/auth.go b/api/v0/auth.go
new file mode 100644
index 00000000..1500188d
--- /dev/null
+++ b/api/v0/auth.go
@@ -0,0 +1,295 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "context"
+ "crypto/subtle"
+ "errors"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/limited"
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+const (
+ clientIdCookieName = "_id"
+
+ clientIdKey = "go-openbmclapi.cluster.client.id"
+)
+
+func apiGetClientId(req *http.Request) (id string) {
+ return req.Context().Value(clientIdKey).(string)
+}
+
+const jwtIssuerPrefix = "GOBA.dash.api"
+
+const (
+ tokenTypeKey = "go-openbmclapi.cluster.token.typ"
+ tokenIdKey = "go-openbmclapi.cluster.token.id"
+
+ loggedUserKey = "go-openbmclapi.cluster.logged.user"
+)
+
+const (
+ tokenTypeAuth = "auth"
+ tokenTypeAPI = "api"
+)
+
+func getRequestTokenType(req *http.Request) string {
+ if t, ok := req.Context().Value(tokenTypeKey).(string); ok {
+ return t
+ }
+ return ""
+}
+
+func getLoggedUser(req *http.Request) *api.User {
+ if user, ok := req.Context().Value(loggedUserKey).(*api.User); ok {
+ return user
+ }
+ return nil
+}
+
+func cliIdMiddleWare(rw http.ResponseWriter, req *http.Request, next http.Handler) {
+ var id string
+ if cid, _ := req.Cookie(clientIdCookieName); cid != nil {
+ id = cid.Value
+ } else {
+ var err error
+ id, err = utils.GenRandB64(16)
+ if err != nil {
+ http.Error(rw, "cannot generate random number", http.StatusInternalServerError)
+ return
+ }
+ http.SetCookie(rw, &http.Cookie{
+ Name: clientIdCookieName,
+ Value: id,
+ Expires: time.Now().Add(time.Hour * 24 * 365 * 16),
+ Secure: true,
+ HttpOnly: true,
+ })
+ }
+ req = req.WithContext(context.WithValue(req.Context(), clientIdKey, utils.AsSha256(id)))
+ next.ServeHTTP(rw, req)
+}
+
+func (h *Handler) authMiddleWare(rw http.ResponseWriter, req *http.Request, next http.Handler) {
+ cli := apiGetClientId(req)
+
+ ctx := req.Context()
+
+ var (
+ typ string
+ id string
+ uid string
+ err error
+ )
+ if req.Method == http.MethodGet {
+ if tk := req.URL.Query().Get("_t"); tk != "" {
+ path := api.GetRequestRealPath(req)
+ if uid, err = h.tokens.VerifyAPIToken(cli, tk, path, req.URL.Query()); err == nil {
+ typ = tokenTypeAPI
+ }
+ }
+ }
+ if typ == "" {
+ auth := req.Header.Get("Authorization")
+ tk, ok := strings.CutPrefix(auth, "Bearer ")
+ if !ok {
+ if err == nil {
+ err = errors.New("Unsupported authorization type")
+ }
+ } else if id, uid, err = h.tokens.VerifyAuthToken(cli, tk); err == nil {
+ typ = tokenTypeAuth
+ }
+ }
+ if typ != "" {
+ user := h.users.GetUser(uid)
+ if user != nil {
+ ctx = context.WithValue(ctx, tokenTypeKey, typ)
+ ctx = context.WithValue(ctx, loggedUserKey, user)
+ ctx = context.WithValue(ctx, tokenIdKey, id)
+ req = req.WithContext(ctx)
+ if user.HasPerm(api.RootPerm) {
+ req = limited.SetSkipRateLimit(req)
+ }
+ }
+ }
+ next.ServeHTTP(rw, req)
+}
+
+func authHandle(next http.Handler) http.Handler {
+ return permHandle(api.BasicPerm, next)
+}
+
+func authHandleFunc(next http.HandlerFunc) http.Handler {
+ return authHandle(next)
+}
+
+func permHandle(perm api.PermissionFlag, next http.Handler) http.Handler {
+ perm |= api.BasicPerm
+ return (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ if user == nil {
+ writeJson(rw, http.StatusUnauthorized, Map{
+ "error": "403 Unauthorized",
+ })
+ return
+ }
+ if user.Permissions&perm != perm {
+ writeJson(rw, http.StatusForbidden, Map{
+ "error": "Permission denied",
+ })
+ return
+ }
+ next.ServeHTTP(rw, req)
+ })
+}
+
+func permHandleFunc(perm api.PermissionFlag, next http.HandlerFunc) http.Handler {
+ return permHandle(perm, next)
+}
+
+func (h *Handler) buildAuthRoute(mux *http.ServeMux) {
+ mux.HandleFunc("/challenge", h.routeChallenge)
+ mux.HandleFunc("POST /login", h.routeLogin)
+ mux.Handle("POST /requestToken", authHandleFunc(h.routeRequestToken))
+ mux.Handle("POST /logout", authHandleFunc(h.routeLogout))
+ mux.Handle("GET /user_info", authHandleFunc(h.routeUserInfo))
+}
+
+func (h *Handler) routeChallenge(rw http.ResponseWriter, req *http.Request) {
+ if req.Method != http.MethodGet {
+ errorMethodNotAllowed(rw, req, http.MethodGet)
+ return
+ }
+ cli := apiGetClientId(req)
+ query := req.URL.Query()
+ action := query.Get("action")
+ token, err := h.tokens.GenerateChallengeToken(cli, action)
+ if err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "Cannot generate token",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "token": token,
+ })
+}
+
+func (h *Handler) routeLogin(rw http.ResponseWriter, req *http.Request) {
+ cli := apiGetClientId(req)
+
+ var data struct {
+ User string `json:"username" schema:"username"`
+ Challenge string `json:"challenge" schema:"challenge"`
+ Signature string `json:"signature" schema:"signature"`
+ }
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+
+ if err := h.tokens.VerifyChallengeToken(cli, "login", data.Challenge); err != nil {
+ writeJson(rw, http.StatusUnauthorized, Map{
+ "error": "Invalid challenge",
+ })
+ return
+ }
+ if err := h.users.VerifyUserPassword(data.User, func(password string) bool {
+ expectSignature := utils.HMACSha256HexBytes(password, data.Challenge)
+ return subtle.ConstantTimeCompare(expectSignature, ([]byte)(data.Signature)) == 0
+ }); err != nil {
+ writeJson(rw, http.StatusUnauthorized, Map{
+ "error": "The username or password is incorrect",
+ })
+ return
+ }
+ token, err := h.tokens.GenerateAuthToken(cli, data.User)
+ if err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "Cannot generate token",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "token": token,
+ })
+}
+
+func (h *Handler) routeRequestToken(rw http.ResponseWriter, req *http.Request) {
+ defer req.Body.Close()
+ if getRequestTokenType(req) != tokenTypeAuth {
+ writeJson(rw, http.StatusUnauthorized, Map{
+ "error": "invalid authorization type",
+ })
+ return
+ }
+
+ var payload struct {
+ Path string `json:"path"`
+ Query map[string]string `json:"query,omitempty"`
+ }
+ if !parseRequestBody(rw, req, &payload) {
+ return
+ }
+ log.Debugf("payload: %#v", payload)
+ if payload.Path == "" || payload.Path[0] != '/' {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "path is invalid",
+ "message": "'path' must be a non empty string which starts with '/'",
+ })
+ return
+ }
+ cli := apiGetClientId(req)
+ user := getLoggedUser(req)
+ token, err := h.tokens.GenerateAPIToken(cli, user.Username, payload.Path, payload.Query)
+ if err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "cannot generate token",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "token": token,
+ })
+}
+
+func (h *Handler) routeLogout(rw http.ResponseWriter, req *http.Request) {
+ limited.SetSkipRateLimit(req)
+ tid := req.Context().Value(tokenIdKey).(string)
+ h.tokens.InvalidToken(tid)
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeUserInfo(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ writeJson(rw, http.StatusOK, Map{
+ "name": user.Username,
+ "permissions": user.Permissions,
+ })
+}
diff --git a/api/v0/cluster.go b/api/v0/cluster.go
new file mode 100644
index 00000000..76812bd8
--- /dev/null
+++ b/api/v0/cluster.go
@@ -0,0 +1,295 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2025 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "mime"
+ "net/http"
+ "strconv"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/config"
+ "github.com/LiterMC/go-openbmclapi/log"
+)
+
+func (h *Handler) buildClusterRoute(mux *http.ServeMux) {
+ mux.Handle("GET /cluster/list", permHandleFunc(api.ClusterPerm, h.routeClusterList))
+ mux.Handle("GET /cluster/status", permHandleFunc(api.ClusterPerm, h.routeClusterStatus))
+ mux.Handle("GET /cluster/config", permHandleFunc(api.ClusterPerm, h.routeClusterConfigGET))
+ mux.Handle("PUT /cluster/config", permHandleFunc(api.ClusterPerm, h.routeClusterConfigPUT))
+ mux.Handle("DELETE /cluster/config", permHandleFunc(api.ClusterPerm, h.routeClusterConfigDELETE))
+ mux.Handle("POST /cluster/connect", permHandleFunc(api.ClusterPerm, h.routeClusterConnect))
+ mux.Handle("POST /cluster/sync", permHandleFunc(api.ClusterPerm, h.routeClusterSync))
+ mux.Handle("POST /cluster/enable", permHandleFunc(api.ClusterPerm, h.routeClusterEnable))
+ mux.Handle("POST /cluster/disable", permHandleFunc(api.ClusterPerm, h.routeClusterDisable))
+}
+
+func (h *Handler) routeClusterList(rw http.ResponseWriter, req *http.Request) {
+ data, err := json.Marshal(h.config.GetConfig().Clusters)
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "MarshalJSONError",
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := calcSha256ETag(data)
+ rw.Header().Set("ETag", etag)
+ if req.Header.Get("If-None-Match") == etag {
+ rw.WriteHeader(http.StatusNotModified)
+ return
+ }
+ rw.Header().Set("Content-Type", "application/json")
+ rw.Header().Set("Content-Length", strconv.Itoa(len(data)))
+ rw.WriteHeader(http.StatusOK)
+ rw.Write(data)
+}
+
+func (h *Handler) routeClusterStatus(rw http.ResponseWriter, req *http.Request) {
+ type clusterStatus struct {
+ Status api.ClusterStatus `json:"status"`
+ Sync bool `json:"sync"`
+ }
+ data := make(map[string]*clusterStatus)
+ for _, cluster := range h.clusters.GetClusters() {
+ data[cluster.Name()] = &clusterStatus{
+ Status: cluster.Status(),
+ Sync: false, // TODO
+ }
+ }
+ writeJson(rw, http.StatusOK, data)
+}
+
+func (h *Handler) routeClusterConfigGET(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ clusterCfg, ok := h.config.GetConfig().Clusters[clusterId]
+ if !ok {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "ClusterNotFound",
+ })
+ return
+ }
+ data, err := json.Marshal(clusterCfg)
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "MarshalJSONError",
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := calcSha256ETag(data)
+ rw.Header().Set("ETag", etag)
+ if req.Header.Get("If-None-Match") == etag {
+ rw.WriteHeader(http.StatusNotModified)
+ return
+ }
+ rw.Header().Set("Content-Type", "application/json")
+ rw.Header().Set("Content-Length", strconv.Itoa(len(data)))
+ rw.WriteHeader(http.StatusOK)
+ rw.Write(data)
+}
+
+func (h *Handler) routeClusterConfigPUT(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ contentType, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
+ if err != nil {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := req.Header.Get("If-Match")
+ if err := h.config.DoWriteLockedAction(func(cfg api.ConfigHandler) error {
+ clustersCfg := cfg.GetConfig().Clusters
+ if etag != "" {
+ ccfg, ok := clustersCfg[clusterId]
+ if !ok {
+ return api.ErrPreconditionFailed
+ }
+ if data, err := json.Marshal(ccfg); err != nil {
+ return err
+ } else if etag != calcSha256ETag(data) {
+ return api.ErrPreconditionFailed
+ }
+ }
+ var clusterCfg config.ClusterOptions
+ switch contentType {
+ case "application/json":
+ buf, err := io.ReadAll(req.Body)
+ if err != nil {
+ return fmt.Errorf("Failed to read request body: %w", err)
+ }
+ if err := json.Unmarshal(buf, &clusterCfg); err != nil {
+ return err
+ }
+ default:
+ return errUnknownContent
+ }
+ clustersCfg[clusterId] = clusterCfg
+ return nil
+ }); err != nil {
+ if err == api.ErrPreconditionFailed {
+ rw.WriteHeader(http.StatusPreconditionFailed)
+ return
+ }
+ if err == errUnknownContent {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": "Expected application/json",
+ })
+ return
+ }
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "UnmarshalError",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeClusterConfigDELETE(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ etag := req.Header.Get("If-Match")
+ if err := h.config.DoWriteLockedAction(func(config api.ConfigHandler) error {
+ clustersCfg := h.config.GetConfig().Clusters
+ if etag != "" {
+ buf, err := json.Marshal(clustersCfg)
+ if err != nil {
+ return err
+ }
+ if etag != calcSha256ETag(buf) {
+ return api.ErrPreconditionFailed
+ }
+ }
+ _, ok := clustersCfg[clusterId]
+ if !ok {
+ return api.ErrPreconditionFailed
+ }
+ delete(clustersCfg, clusterId)
+ return nil
+ }); err != nil {
+ if err == api.ErrPreconditionFailed {
+ rw.WriteHeader(http.StatusPreconditionFailed)
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "InternalServerError",
+ "message": err.Error(),
+ })
+ return
+ }
+ cluster := h.clusters.GetCluster(clusterId)
+ if cluster == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "ClusterNotFound",
+ })
+ return
+ }
+ go func() {
+ if err := cluster.Disable(context.Background()); err != nil {
+ log.Errorf("API Disable Error: %v", err)
+ }
+ cluster.Disconnect(context.Background())
+ }()
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeClusterConnect(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ cluster := h.clusters.GetCluster(clusterId)
+ if cluster == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "ClusterNotFound",
+ })
+ return
+ }
+ go func() {
+ err := cluster.Connect(context.Background())
+ if err != nil {
+ log.Errorf("API Connect Error: %v", err)
+ }
+ }()
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeClusterSync(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ clu := h.clusters.GetCluster(clusterId)
+ fileMap := make(map[string]*api.StorageFileInfo)
+ if err := clu.GetFileList(req.Context(), fileMap, false); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "FileListFetchError",
+ "message": err.Error(),
+ })
+ return
+ }
+ go func() {
+ // TODO: sync file
+ // need make sure no conflict with timed sync
+ }()
+ writeJson(rw, http.StatusOK, Map{
+ "count": len(fileMap),
+ })
+}
+
+func (h *Handler) routeClusterEnable(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ cluster := h.clusters.GetCluster(clusterId)
+ if cluster == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "ClusterNotFound",
+ })
+ return
+ }
+ go func() {
+ err := cluster.Enable(context.Background())
+ if err != nil {
+ log.Errorf("API Enable Error: %v", err)
+ }
+ }()
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeClusterDisable(rw http.ResponseWriter, req *http.Request) {
+ clusterId := req.URL.Query().Get("cluster_id")
+ cluster := h.clusters.GetCluster(clusterId)
+ if cluster == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "ClusterNotFound",
+ })
+ return
+ }
+ go func() {
+ err := cluster.Disable(context.Background())
+ if err != nil {
+ log.Errorf("API Disable Error: %v", err)
+ }
+ cluster.Disconnect(context.Background())
+ }()
+ rw.WriteHeader(http.StatusNoContent)
+}
diff --git a/api/v0/configure.go b/api/v0/configure.go
new file mode 100644
index 00000000..bd8b8fac
--- /dev/null
+++ b/api/v0/configure.go
@@ -0,0 +1,258 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "fmt"
+ "io"
+ "mime"
+ "net/http"
+ "strconv"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+)
+
+func (h *Handler) buildConfigureRoute(mux *http.ServeMux) {
+ mux.Handle("GET /config", permHandleFunc(api.FullConfigPerm, h.routeConfigGET))
+ mux.Handle("GET /config/{path}", permHandleFunc(api.FullConfigPerm, h.routeConfigGETPath))
+ mux.Handle("PUT /config", permHandleFunc(api.FullConfigPerm, h.routeConfigPUT))
+ mux.Handle("PATCH /config/{path}", permHandleFunc(api.FullConfigPerm, h.routeConfigPATCH))
+
+ mux.Handle("GET /configure/storages", permHandleFunc(api.StoragePerm, h.routeConfigureStoragesGET))
+ mux.Handle("GET /configure/storage/{storage_index}", permHandleFunc(api.StoragePerm, h.routeConfigureStorageGET))
+ mux.Handle("PUT /configure/storage/{storage_index}", permHandleFunc(api.StoragePerm, h.routeConfigureStoragePUT))
+ mux.Handle("PATCH /configure/storage/{storage_index}/{path}", permHandleFunc(api.StoragePerm, h.routeConfigureStoragePATCH))
+ mux.Handle("DELETE /configure/storage/{storage_index}", permHandleFunc(api.StoragePerm, h.routeConfigureStorageDELETE))
+ mux.Handle("POST /configure/storage/{storage_index}/move", permHandleFunc(api.StoragePerm, h.routeConfigureStorageMove))
+}
+
+func (h *Handler) routeConfigGET(rw http.ResponseWriter, req *http.Request) {
+ buf, err := h.config.MarshalJSON()
+ if err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "MarshalJSONError",
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := calcSha256ETag(buf)
+ rw.Header().Set("ETag", etag)
+ if req.Header.Get("If-None-Match") == etag {
+ rw.WriteHeader(http.StatusNotModified)
+ return
+ }
+ rw.WriteHeader(http.StatusOK)
+ rw.Write(buf)
+}
+
+func (h *Handler) routeConfigPUT(rw http.ResponseWriter, req *http.Request) {
+ contentType, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
+ if err != nil {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := req.Header.Get("If-Match")
+ if err := h.config.DoWriteLockedAction(func(config api.ConfigHandler) error {
+ if etag != "" {
+ buf, err := config.GetConfig().MarshalJSON()
+ if err != nil {
+ return err
+ }
+ if etag != calcSha256ETag(buf) {
+ return api.ErrPreconditionFailed
+ }
+ }
+ switch contentType {
+ case "application/json":
+ buf, err := io.ReadAll(req.Body)
+ if err != nil {
+ return fmt.Errorf("Failed to read request body: %w", err)
+ }
+ return config.UnmarshalJSON(buf)
+ case "application/x-yaml":
+ buf, err := io.ReadAll(req.Body)
+ if err != nil {
+ return fmt.Errorf("Failed to read request body: %w", err)
+ }
+ return config.UnmarshalYAML(buf)
+ default:
+ return errUnknownContent
+ }
+ }); err != nil {
+ if err == api.ErrPreconditionFailed {
+ rw.WriteHeader(http.StatusPreconditionFailed)
+ return
+ }
+ if err == errUnknownContent {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": "Expected application/json, application/x-yaml",
+ })
+ return
+ }
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "UnmarshalError",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+ // TODO: restart
+}
+
+func (h *Handler) routeConfigGETPath(rw http.ResponseWriter, req *http.Request) {
+ path := req.PathValue("path")
+ data, err := h.config.MarshalJSONPath(path)
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "MarshalJSONError",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.Header().Set("Content-Type", "application/json")
+ rw.Header().Set("Content-Length", strconv.Itoa(len(data)))
+ rw.WriteHeader(http.StatusOK)
+ rw.Write(data)
+}
+
+func (h *Handler) routeConfigPATCH(rw http.ResponseWriter, req *http.Request) {
+ path := req.PathValue("path")
+ contentType, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
+ if err != nil {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": err.Error(),
+ })
+ return
+ }
+ etag := req.Header.Get("If-Match")
+ if err := h.config.DoWriteLockedAction(func(config api.ConfigHandler) error {
+ if etag != "" {
+ buf, err := config.GetConfig().MarshalJSON()
+ if err != nil {
+ return err
+ }
+ if etag != calcSha256ETag(buf) {
+ return api.ErrPreconditionFailed
+ }
+ }
+ switch contentType {
+ case "application/json":
+ buf, err := io.ReadAll(req.Body)
+ if err != nil {
+ return fmt.Errorf("Failed to read request body: %w", err)
+ }
+ return config.UnmarshalJSONPath(path, buf)
+ default:
+ return errUnknownContent
+ }
+ }); err != nil {
+ if err == api.ErrPreconditionFailed {
+ rw.WriteHeader(http.StatusPreconditionFailed)
+ return
+ }
+ if err == errUnknownContent {
+ writeJson(rw, http.StatusUnsupportedMediaType, Map{
+ "error": "Unexpected Content-Type",
+ "content-type": req.Header.Get("Content-Type"),
+ "message": "Expected application/json, application/x-yaml",
+ })
+ return
+ }
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "UnmarshalError",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeConfigureStoragesGET(rw http.ResponseWriter, req *http.Request) {
+}
+
+func (h *Handler) routeConfigureStorageGET(rw http.ResponseWriter, req *http.Request) {
+ storageIndex, err := strconv.Atoi(req.PathValue("storage_index"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected storageIndex",
+ "message": err.Error(),
+ })
+ return
+ }
+ _ = storageIndex
+}
+
+func (h *Handler) routeConfigureStoragePUT(rw http.ResponseWriter, req *http.Request) {
+ storageIndex, err := strconv.Atoi(req.PathValue("storage_index"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected storageIndex",
+ "message": err.Error(),
+ })
+ return
+ }
+ _ = storageIndex
+}
+
+func (h *Handler) routeConfigureStoragePATCH(rw http.ResponseWriter, req *http.Request) {
+ storageIndex, err := strconv.Atoi(req.PathValue("storage_index"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected storageIndex",
+ "message": err.Error(),
+ })
+ return
+ }
+ path := req.PathValue("path")
+ _, _ = storageIndex, path
+}
+
+func (h *Handler) routeConfigureStorageDELETE(rw http.ResponseWriter, req *http.Request) {
+ storageIndex, err := strconv.Atoi(req.PathValue("storage_index"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected storageIndex",
+ "message": err.Error(),
+ })
+ return
+ }
+ _ = storageIndex
+}
+
+func (h *Handler) routeConfigureStorageMove(rw http.ResponseWriter, req *http.Request) {
+ storageIndex, err := strconv.Atoi(req.PathValue("storage_index"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "Unexpected storageIndex",
+ "message": err.Error(),
+ })
+ return
+ }
+ storageIndexTo := req.URL.Query().Get("to")
+ _, _ = storageIndex, storageIndexTo
+}
diff --git a/api/v0/debug.go b/api/v0/debug.go
new file mode 100644
index 00000000..9727d627
--- /dev/null
+++ b/api/v0/debug.go
@@ -0,0 +1,393 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2023 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "compress/gzip"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+ "runtime/pprof"
+ "strconv"
+ "sync/atomic"
+ "time"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+func (h *Handler) buildDebugRoute(mux *http.ServeMux) {
+ mux.HandleFunc("/log.io", h.routeLogIO)
+ mux.Handle("/pprof", permHandleFunc(api.DebugPerm, h.routePprof))
+ mux.Handle("GET /log_files", permHandleFunc(api.LogPerm, h.routeLogFiles))
+ mux.Handle("GET /log_file/{file_name}", permHandleFunc(api.LogPerm, h.routeLogFile))
+}
+
+func (h *Handler) routeLogIO(rw http.ResponseWriter, req *http.Request) {
+ addr := api.GetRequestRealAddr(req)
+
+ conn, err := h.wsUpgrader.Upgrade(rw, req, nil)
+ if err != nil {
+ log.Debugf("[log.io]: Websocket upgrade error: %v", err)
+ http.Error(rw, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ defer conn.Close()
+
+ cli := apiGetClientId(req)
+
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+
+ conn.SetReadLimit(1024 * 4)
+ pongTimeoutTimer := time.NewTimer(time.Second * 75)
+ go func() {
+ defer conn.Close()
+ defer cancel()
+ defer pongTimeoutTimer.Stop()
+ select {
+ case _, ok := <-pongTimeoutTimer.C:
+ if !ok {
+ return
+ }
+ log.Error("[log.io]: Did not receive packet from client longer than 75s")
+ return
+ case <-ctx.Done():
+ return
+ }
+ }()
+
+ var authData struct {
+ Token string `json:"token"`
+ }
+ deadline := time.Now().Add(time.Second * 10)
+ conn.SetReadDeadline(deadline)
+ err = conn.ReadJSON(&authData)
+ conn.SetReadDeadline(time.Time{})
+ if err != nil {
+ if time.Now().After(deadline) {
+ conn.WriteJSON(Map{
+ "type": "error",
+ "message": "auth timeout",
+ })
+ } else {
+ conn.WriteJSON(Map{
+ "type": "error",
+ "message": "unexpected auth data: " + err.Error(),
+ })
+ }
+ return
+ }
+ if _, _, err = h.tokens.VerifyAuthToken(cli, authData.Token); err != nil {
+ conn.WriteJSON(Map{
+ "type": "error",
+ "message": "auth failed",
+ })
+ return
+ }
+ if err := conn.WriteJSON(Map{
+ "type": "ready",
+ }); err != nil {
+ return
+ }
+
+ var level atomic.Int32
+ level.Store((int32)(log.LevelInfo))
+
+ type logObj struct {
+ Type string `json:"type"`
+ Time int64 `json:"time"` // UnixMilli
+ Level string `json:"lvl"`
+ Log string `json:"log"`
+ }
+ c := make(chan *logObj, 64)
+ unregister := log.RegisterLogMonitor(log.LevelDebug, func(ts int64, l log.Level, msg string) {
+ if (log.Level)(level.Load()) > l&log.LevelMask {
+ return
+ }
+ select {
+ case c <- &logObj{
+ Type: "log",
+ Time: ts,
+ Level: l.String(),
+ Log: msg,
+ }:
+ default:
+ }
+ })
+ defer unregister()
+
+ go func() {
+ defer log.RecoverPanic(nil)
+ defer conn.Close()
+ defer cancel()
+ var data map[string]any
+ for {
+ clear(data)
+ if err := conn.ReadJSON(&data); err != nil {
+ log.Errorf("[log.io]: Cannot read from peer: %v", err)
+ return
+ }
+ typ, ok := data["type"].(string)
+ if !ok {
+ continue
+ }
+ switch typ {
+ case "pong":
+ log.Debugf("[log.io]: received PONG from %s: %v", addr, data["data"])
+ pongTimeoutTimer.Reset(time.Second * 75)
+ case "set-level":
+ l, ok := data["level"].(string)
+ if ok {
+ switch l {
+ case "DBUG":
+ level.Store((int32)(log.LevelDebug))
+ case "INFO":
+ level.Store((int32)(log.LevelInfo))
+ case "WARN":
+ level.Store((int32)(log.LevelWarn))
+ case "ERRO":
+ level.Store((int32)(log.LevelError))
+ default:
+ continue
+ }
+ select {
+ case c <- &logObj{
+ Type: "log",
+ Time: time.Now().UnixMilli(),
+ Level: log.LevelInfo.String(),
+ Log: "[dashboard]: Set log level to " + l + " for this log.io",
+ }:
+ default:
+ }
+ }
+ }
+ }
+ }()
+
+ sendMsgCh := make(chan any, 64)
+ go func() {
+ for {
+ select {
+ case v := <-c:
+ select {
+ case sendMsgCh <- v:
+ case <-ctx.Done():
+ return
+ }
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
+
+ pingTicker := time.NewTicker(time.Second * 45)
+ defer pingTicker.Stop()
+ forceSendTimer := time.NewTimer(time.Second)
+ if !forceSendTimer.Stop() {
+ <-forceSendTimer.C
+ }
+
+ batchMsg := make([]any, 0, 64)
+ for {
+ select {
+ case v := <-sendMsgCh:
+ batchMsg = append(batchMsg, v)
+ forceSendTimer.Reset(time.Second)
+ WAIT_MORE:
+ for {
+ select {
+ case v := <-sendMsgCh:
+ batchMsg = append(batchMsg, v)
+ case <-time.After(time.Millisecond * 20):
+ if !forceSendTimer.Stop() {
+ <-forceSendTimer.C
+ }
+ break WAIT_MORE
+ case <-forceSendTimer.C:
+ break WAIT_MORE
+ case <-ctx.Done():
+ forceSendTimer.Stop()
+ return
+ }
+ }
+ if len(batchMsg) == 1 {
+ if err := conn.WriteJSON(batchMsg[0]); err != nil {
+ return
+ }
+ } else {
+ if err := conn.WriteJSON(batchMsg); err != nil {
+ return
+ }
+ }
+ // release objects
+ for i, _ := range batchMsg {
+ batchMsg[i] = nil
+ }
+ batchMsg = batchMsg[:0]
+ case <-pingTicker.C:
+ if err := conn.WriteJSON(Map{
+ "type": "ping",
+ "data": time.Now().UnixMilli(),
+ }); err != nil {
+ log.Errorf("[log.io]: Error when sending ping packet: %v", err)
+ return
+ }
+ case <-ctx.Done():
+ return
+ }
+ }
+}
+
+func (h *Handler) routePprof(rw http.ResponseWriter, req *http.Request) {
+ if req.Method != http.MethodGet {
+ errorMethodNotAllowed(rw, req, http.MethodGet)
+ return
+ }
+ query := req.URL.Query()
+ lookup := query.Get("lookup")
+ p := pprof.Lookup(lookup)
+ if p == nil {
+ http.Error(rw, fmt.Sprintf("pprof.Lookup(%q) returned nil", lookup), http.StatusBadRequest)
+ return
+ }
+ view := query.Get("view")
+ debug, err := strconv.Atoi(query.Get("debug"))
+ if err != nil {
+ debug = 1
+ }
+ if debug == 1 {
+ rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ } else {
+ rw.Header().Set("Content-Type", "application/octet-stream")
+ }
+ if view != "1" {
+ name := fmt.Sprintf(time.Now().Format("dump-%s-20060102-150405"), lookup)
+ if debug == 1 {
+ name += ".txt"
+ } else {
+ name += ".dump"
+ }
+ rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name))
+ }
+ rw.WriteHeader(http.StatusOK)
+ if debug == 1 {
+ fmt.Fprintf(rw, "version: %s (%s)\n", build.BuildVersion, build.ClusterVersion)
+ }
+ p.WriteTo(rw, debug)
+}
+
+func (h *Handler) routeLogFiles(rw http.ResponseWriter, req *http.Request) {
+ files := log.ListLogs()
+ type FileInfo struct {
+ Name string `json:"name"`
+ Size int64 `json:"size"`
+ }
+ data := make([]FileInfo, 0, len(files))
+ for _, file := range files {
+ if s, err := os.Stat(filepath.Join(log.BaseDir(), file)); err == nil {
+ data = append(data, FileInfo{
+ Name: file,
+ Size: s.Size(),
+ })
+ }
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "files": data,
+ })
+}
+
+func (h *Handler) routeLogFile(rw http.ResponseWriter, req *http.Request) {
+ fileName := req.PathValue("file_name")
+ query := req.URL.Query()
+ fd, err := os.Open(filepath.Join(log.BaseDir(), fileName))
+ if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "file not exists",
+ "message": "Cannot find log file",
+ "path": req.URL.Path,
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "cannot open file",
+ "message": err.Error(),
+ })
+ return
+ }
+ defer fd.Close()
+ name := filepath.Base(req.URL.Path)
+ isGzip := filepath.Ext(name) == ".gz"
+ if query.Get("no_encrypt") == "1" {
+ var modTime time.Time
+ if stat, err := fd.Stat(); err == nil {
+ modTime = stat.ModTime()
+ }
+ rw.Header().Set("Cache-Control", "public, max-age=60, stale-while-revalidate=600")
+ if isGzip {
+ rw.Header().Set("Content-Type", "application/octet-stream")
+ } else {
+ rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ }
+ rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name))
+ http.ServeContent(rw, req, name, modTime, fd)
+ } else {
+ if !isGzip {
+ name += ".gz"
+ }
+ rw.Header().Set("Content-Type", "application/octet-stream")
+ rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name+".encrypted"))
+ h.routeLogFileEncrypted(rw, req, fd, !isGzip)
+ }
+}
+
+func (h *Handler) routeLogFileEncrypted(rw http.ResponseWriter, req *http.Request, r io.Reader, useGzip bool) {
+ rw.WriteHeader(http.StatusOK)
+ if req.Method == http.MethodHead {
+ return
+ }
+ if useGzip {
+ pr, pw := io.Pipe()
+ defer pr.Close()
+ go func(r io.Reader) {
+ gw := gzip.NewWriter(pw)
+ if _, err := io.Copy(gw, r); err != nil {
+ pw.CloseWithError(err)
+ return
+ }
+ if err := gw.Close(); err != nil {
+ pw.CloseWithError(err)
+ return
+ }
+ pw.Close()
+ }(r)
+ r = pr
+ }
+ if err := utils.EncryptStream(rw, r, utils.DeveloporPublicKey); err != nil {
+ log.Errorf("Cannot write encrypted log stream: %v", err)
+ }
+}
diff --git a/api/v0/stat.go b/api/v0/stat.go
new file mode 100644
index 00000000..09b26b5e
--- /dev/null
+++ b/api/v0/stat.go
@@ -0,0 +1,78 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2023 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+ "github.com/LiterMC/go-openbmclapi/limited"
+)
+
+func (h *Handler) buildStatRoute(mux *http.ServeMux) {
+ mux.HandleFunc("GET /ping", h.routePing)
+ mux.HandleFunc("GET /status", h.routeStatus)
+ mux.HandleFunc("GET /stat/cluster/{name}", h.routeStatCluster)
+ mux.HandleFunc("GET /stat/storage/{name}", h.routeStatStorage)
+}
+
+func (h *Handler) routePing(rw http.ResponseWriter, req *http.Request) {
+ limited.SetSkipRateLimit(req)
+ authed := getRequestTokenType(req) == tokenTypeAuth
+ writeJson(rw, http.StatusOK, Map{
+ "version": build.BuildVersion,
+ "time": time.Now().UnixMilli(),
+ "authed": authed,
+ })
+}
+
+func (h *Handler) routeStatus(rw http.ResponseWriter, req *http.Request) {
+ limited.SetSkipRateLimit(req)
+ writeJson(rw, http.StatusOK, h.stats.GetStatus())
+}
+
+func (h *Handler) routeStatCluster(rw http.ResponseWriter, req *http.Request) {
+ limited.SetSkipRateLimit(req)
+ name := req.PathValue("name")
+ data := h.stats.GetClusterAccessStat(name)
+ if data == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "AccessStatNotFound",
+ "name": name,
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, data)
+}
+
+func (h *Handler) routeStatStorage(rw http.ResponseWriter, req *http.Request) {
+ limited.SetSkipRateLimit(req)
+ name := req.PathValue("name")
+ data := h.stats.GetStorageAccessStat(name)
+ if data == nil {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "AccessStatNotFound",
+ "name": name,
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, data)
+}
diff --git a/api/v0/subscription.go b/api/v0/subscription.go
new file mode 100644
index 00000000..cdf30fc7
--- /dev/null
+++ b/api/v0/subscription.go
@@ -0,0 +1,338 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2023 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package v0
+
+import (
+ "net/http"
+
+ "github.com/google/uuid"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+func (h *Handler) buildSubscriptionRoute(mux *http.ServeMux) {
+ mux.HandleFunc("GET /subscribeKey", h.routeSubscribeKey)
+ mux.Handle("/subscribe", permHandle(api.SubscribePerm, &utils.HttpMethodHandler{
+ Get: (http.HandlerFunc)(h.routeSubscribeGET),
+ Post: (http.HandlerFunc)(h.routeSubscribePOST),
+ Delete: (http.HandlerFunc)(h.routeSubscribeDELETE),
+ }))
+ mux.Handle("/subscribe_email", permHandle(api.SubscribePerm, &utils.HttpMethodHandler{
+ Get: (http.HandlerFunc)(h.routeSubscribeEmailGET),
+ Post: (http.HandlerFunc)(h.routeSubscribeEmailPOST),
+ Patch: (http.HandlerFunc)(h.routeSubscribeEmailPATCH),
+ Delete: (http.HandlerFunc)(h.routeSubscribeEmailDELETE),
+ }))
+ mux.Handle("/webhook", permHandle(api.SubscribePerm, &utils.HttpMethodHandler{
+ Get: (http.HandlerFunc)(h.routeWebhookGET),
+ Post: (http.HandlerFunc)(h.routeWebhookPOST),
+ Patch: (http.HandlerFunc)(h.routeWebhookPATCH),
+ Delete: (http.HandlerFunc)(h.routeWebhookDELETE),
+ }))
+}
+
+func (h *Handler) routeSubscribeKey(rw http.ResponseWriter, req *http.Request) {
+ key := h.subscriptions.GetWebPushKey()
+ etag := `"` + utils.AsSha256(key) + `"`
+ rw.Header().Set("ETag", etag)
+ if cachedTag := req.Header.Get("If-None-Match"); cachedTag == etag {
+ rw.WriteHeader(http.StatusNotModified)
+ return
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "publicKey": key,
+ })
+}
+
+func (h *Handler) routeSubscribeGET(rw http.ResponseWriter, req *http.Request) {
+ client := apiGetClientId(req)
+ user := getLoggedUser(req)
+ record, err := h.subscriptions.GetSubscribe(user.Username, client)
+ if err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no subscription was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, Map{
+ "scopes": record.Scopes,
+ "reportAt": record.ReportAt,
+ })
+}
+
+func (h *Handler) routeSubscribePOST(rw http.ResponseWriter, req *http.Request) {
+ client := apiGetClientId(req)
+ user := getLoggedUser(req)
+ var data api.SubscribeRecord
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+ data.User = user.Username
+ data.Client = client
+ if err := h.subscriptions.SetSubscribe(data); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "Database update failed",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeSubscribeDELETE(rw http.ResponseWriter, req *http.Request) {
+ client := apiGetClientId(req)
+ user := getLoggedUser(req)
+ if err := h.subscriptions.RemoveSubscribe(user.Username, client); err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no subscription was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeSubscribeEmailGET(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ if addr := req.URL.Query().Get("addr"); addr != "" {
+ record, err := h.subscriptions.GetEmailSubscription(user.Username, addr)
+ if err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no email subscription was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, record)
+ return
+ }
+ records := make([]api.EmailSubscriptionRecord, 0, 4)
+ if err := h.subscriptions.ForEachUsersEmailSubscription(user.Username, func(rec *api.EmailSubscriptionRecord) error {
+ records = append(records, *rec)
+ return nil
+ }); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, records)
+}
+
+func (h *Handler) routeSubscribeEmailPOST(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ var data api.EmailSubscriptionRecord
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+
+ data.User = user.Username
+ if err := h.subscriptions.AddEmailSubscription(data); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "Database update failed",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusCreated)
+}
+
+func (h *Handler) routeSubscribeEmailPATCH(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ addr := req.URL.Query().Get("addr")
+ var data api.EmailSubscriptionRecord
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+ data.User = user.Username
+ data.Addr = addr
+ if err := h.subscriptions.UpdateEmailSubscription(data); err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no email subscription was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeSubscribeEmailDELETE(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ addr := req.URL.Query().Get("addr")
+ if err := h.subscriptions.RemoveEmailSubscription(user.Username, addr); err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no email subscription was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeWebhookGET(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ if sid := req.URL.Query().Get("id"); sid != "" {
+ id, err := uuid.Parse(sid)
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "uuid format error",
+ "message": err.Error(),
+ })
+ return
+ }
+ record, err := h.subscriptions.GetWebhook(user.Username, id)
+ if err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no webhook was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, record)
+ return
+ }
+ records := make([]api.WebhookRecord, 0, 4)
+ if err := h.subscriptions.ForEachUsersWebhook(user.Username, func(rec *api.WebhookRecord) error {
+ records = append(records, *rec)
+ return nil
+ }); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ writeJson(rw, http.StatusOK, records)
+}
+
+func (h *Handler) routeWebhookPOST(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ var data api.WebhookRecord
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+
+ data.User = user.Username
+ if err := h.subscriptions.AddWebhook(data); err != nil {
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "Database update failed",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusCreated)
+}
+
+func (h *Handler) routeWebhookPATCH(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ id := req.URL.Query().Get("id")
+ var data api.WebhookRecord
+ if !parseRequestBody(rw, req, &data) {
+ return
+ }
+ data.User = user.Username
+ var err error
+ if data.Id, err = uuid.Parse(id); err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "uuid format error",
+ "message": err.Error(),
+ })
+ return
+ }
+ if err := h.subscriptions.UpdateWebhook(data); err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no webhook was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
+
+func (h *Handler) routeWebhookDELETE(rw http.ResponseWriter, req *http.Request) {
+ user := getLoggedUser(req)
+ id, err := uuid.Parse(req.URL.Query().Get("id"))
+ if err != nil {
+ writeJson(rw, http.StatusBadRequest, Map{
+ "error": "uuid format error",
+ "message": err.Error(),
+ })
+ return
+ }
+ if err := h.subscriptions.RemoveWebhook(user.Username, id); err != nil {
+ if err == api.ErrNotFound {
+ writeJson(rw, http.StatusNotFound, Map{
+ "error": "no webhook was found",
+ })
+ return
+ }
+ writeJson(rw, http.StatusInternalServerError, Map{
+ "error": "database error",
+ "message": err.Error(),
+ })
+ return
+ }
+ rw.WriteHeader(http.StatusNoContent)
+}
diff --git a/bar.go b/bar.go
deleted file mode 100644
index a89c29b6..00000000
--- a/bar.go
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * OpenBmclAPI (Golang Edition)
- * Copyright (C) 2023 Kevin Z
- * All rights reserved
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "io"
- "sync/atomic"
- "time"
-
- "github.com/vbauerster/mpb/v8"
-)
-
-type ProxiedReader struct {
- io.Reader
- bar, total *mpb.Bar
- lastRead time.Time
- lastInc *atomic.Int64
-}
-
-func ProxyReader(r io.Reader, bar, total *mpb.Bar, lastInc *atomic.Int64) *ProxiedReader {
- return &ProxiedReader{
- Reader: r,
- bar: bar,
- total: total,
- lastInc: lastInc,
- }
-}
-
-func (p *ProxiedReader) Read(buf []byte) (n int, err error) {
- start := p.lastRead
- if start.IsZero() {
- start = time.Now()
- }
- n, err = p.Reader.Read(buf)
- end := time.Now()
- p.lastRead = end
- used := end.Sub(start)
-
- p.bar.EwmaIncrBy(n, used)
- nowSt := end.UnixNano()
- last := p.lastInc.Swap(nowSt)
- p.total.EwmaIncrBy(n, (time.Duration)(nowSt-last)*time.Nanosecond)
- return
-}
-
-type ProxiedReadSeeker struct {
- io.ReadSeeker
- bar, total *mpb.Bar
- lastRead time.Time
- lastInc *atomic.Int64
-}
-
-func ProxyReadSeeker(r io.ReadSeeker, bar, total *mpb.Bar, lastInc *atomic.Int64) *ProxiedReadSeeker {
- return &ProxiedReadSeeker{
- ReadSeeker: r,
- bar: bar,
- total: total,
- lastInc: lastInc,
- }
-}
-
-func (p *ProxiedReadSeeker) Read(buf []byte) (n int, err error) {
- start := p.lastRead
- if start.IsZero() {
- start = time.Now()
- }
- n, err = p.ReadSeeker.Read(buf)
- end := time.Now()
- p.lastRead = end
- used := end.Sub(start)
-
- p.bar.EwmaIncrBy(n, used)
- nowSt := end.UnixNano()
- last := p.lastInc.Swap(nowSt)
- p.total.EwmaIncrBy(n, (time.Duration)(nowSt-last)*time.Nanosecond)
- return
-}
diff --git a/cache/cache_redis.go b/cache/cache_redis.go
index b88dac74..27a2def3 100644
--- a/cache/cache_redis.go
+++ b/cache/cache_redis.go
@@ -35,11 +35,11 @@ type RedisCache struct {
var _ Cache = (*RedisCache)(nil)
type RedisOptions struct {
- Network string `yaml:"network"`
- Addr string `yaml:"addr"`
- ClientName string `yaml:"client-name"`
- Username string `yaml:"username"`
- Password string `yaml:"password"`
+ Network string `json:"network" yaml:"network"`
+ Addr string `json:"addr" yaml:"addr"`
+ ClientName string `json:"client_name" yaml:"client-name"`
+ Username string `json:"username" yaml:"username"`
+ Password string `json:"password" yaml:"password"`
}
func (o RedisOptions) ToRedis() *redis.Options {
diff --git a/cluster.go b/cluster.go
deleted file mode 100644
index a5a2df67..00000000
--- a/cluster.go
+++ /dev/null
@@ -1,770 +0,0 @@
-/**
- * OpenBmclAPI (Golang Edition)
- * Copyright (C) 2023 Kevin Z
- * All rights reserved
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-package main
-
-import (
- "context"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "net"
- "net/http"
- "os"
- "path/filepath"
- "regexp"
- "runtime"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/LiterMC/socket.io"
- "github.com/LiterMC/socket.io/engine.io"
- "github.com/gorilla/websocket"
- "github.com/gregjones/httpcache"
-
- gocache "github.com/LiterMC/go-openbmclapi/cache"
- "github.com/LiterMC/go-openbmclapi/database"
- "github.com/LiterMC/go-openbmclapi/internal/build"
- "github.com/LiterMC/go-openbmclapi/limited"
- "github.com/LiterMC/go-openbmclapi/log"
- "github.com/LiterMC/go-openbmclapi/notify"
- "github.com/LiterMC/go-openbmclapi/notify/email"
- "github.com/LiterMC/go-openbmclapi/notify/webpush"
- "github.com/LiterMC/go-openbmclapi/storage"
- "github.com/LiterMC/go-openbmclapi/utils"
-)
-
-var (
- reFileHashMismatchError = regexp.MustCompile(` hash mismatch, expected ([0-9a-f]+), got ([0-9a-f]+)`)
-)
-
-type Cluster struct {
- host string // not the public access host, but maybe a public IP, or a host that will be resolved to the IP
- publicHosts []string // should not contains port, can be nil
- publicPort uint16
- clusterId string
- clusterSecret string
- prefix string
- byoc bool
- jwtIssuer string
-
- dataDir string
- maxConn int
- storageOpts []storage.StorageOption
- storages []storage.Storage
- storageWeights []uint
- storageTotalWeight uint
- cache gocache.Cache
- apiHmacKey []byte
- hijackProxy *HjProxy
-
- stats notify.Stats
- lastHits, statOnlyHits atomic.Int32
- lastHbts, statOnlyHbts atomic.Int64
- issync atomic.Bool
- syncProg atomic.Int64
- syncTotal atomic.Int64
-
- mux sync.RWMutex
- enabled atomic.Bool
- disabled chan struct{}
- waitEnable []chan struct{}
- shouldEnable atomic.Bool
- reconnectCount int
- socket *socket.Socket
- cancelKeepalive context.CancelFunc
- downloadMux sync.RWMutex
- downloading map[string]*downloadingItem
- filesetMux sync.RWMutex
- fileset map[string]int64
- authTokenMux sync.RWMutex
- authToken *ClusterToken
-
- client *http.Client
- cachedCli *http.Client
- bufSlots *limited.BufSlots
- database database.DB
- notifyManager *notify.Manager
- webpushKeyB64 string
- updateChecker *time.Ticker
- apiRateLimiter *limited.APIRateMiddleWare
-
- wsUpgrader *websocket.Upgrader
- handlerAPIv0 http.Handler
- handlerAPIv1 http.Handler
- hijackHandler http.Handler
-}
-
-func NewCluster(
- ctx context.Context,
- prefix string,
- baseDir string,
- host string, publicPort uint16,
- clusterId string, clusterSecret string,
- byoc bool, dialer *net.Dialer,
- storageOpts []storage.StorageOption,
- cache gocache.Cache,
-) (cr *Cluster) {
- transport := http.DefaultTransport
- if dialer != nil {
- transport = &http.Transport{
- DialContext: dialer.DialContext,
- }
- }
-
- cachedTransport := transport
- if cache != gocache.NoCache {
- cachedTransport = &httpcache.Transport{
- Transport: transport,
- Cache: gocache.WrapToHTTPCache(gocache.NewCacheWithNamespace(cache, "http@")),
- }
- }
-
- cr = &Cluster{
- host: host,
- publicPort: publicPort,
- clusterId: clusterId,
- clusterSecret: clusterSecret,
- prefix: prefix,
- byoc: byoc,
- jwtIssuer: jwtIssuerPrefix + "#" + clusterId,
-
- dataDir: filepath.Join(baseDir, "data"),
- maxConn: config.DownloadMaxConn,
- storageOpts: storageOpts,
- cache: cache,
-
- disabled: make(chan struct{}, 0),
- fileset: make(map[string]int64, 0),
-
- downloading: make(map[string]*downloadingItem),
-
- client: &http.Client{
- Transport: transport,
- CheckRedirect: redirectChecker,
- },
- cachedCli: &http.Client{
- Transport: cachedTransport,
- CheckRedirect: redirectChecker,
- },
-
- wsUpgrader: &websocket.Upgrader{
- HandshakeTimeout: time.Minute,
- },
- }
- close(cr.disabled)
-
- if cr.maxConn <= 0 {
- panic("download-max-conn must be a positive integer")
- }
- cr.bufSlots = limited.NewBufSlots(cr.maxConn)
-
- {
- var (
- n uint = 0
- wgs = make([]uint, len(storageOpts))
- sts = make([]storage.Storage, len(storageOpts))
- )
- for i, s := range storageOpts {
- sts[i] = storage.NewStorage(s)
- wgs[i] = s.Weight
- n += s.Weight
- }
- cr.storages = sts
- cr.storageWeights = wgs
- cr.storageTotalWeight = n
- }
- return
-}
-
-func redirectChecker(req *http.Request, via []*http.Request) error {
- req.Header.Del("Referer")
- if len(via) > 10 {
- return errors.New("More than 10 redirects detected")
- }
- return nil
-}
-
-func (cr *Cluster) Init(ctx context.Context) (err error) {
- // create data folder
- os.MkdirAll(cr.dataDir, 0755)
-
- if config.Database.Driver == "memory" {
- cr.database = database.NewMemoryDB()
- } else if cr.database, err = database.NewSqlDB(config.Database.Driver, config.Database.DSN); err != nil {
- return
- }
-
- if config.Hijack.Enable {
- cr.hijackProxy = NewHjProxy(cr.client, cr.database, cr.handleDownload)
- if config.Hijack.EnableLocalCache {
- os.MkdirAll(config.Hijack.LocalCachePath, 0755)
- }
- }
-
- // Init notification manager
- cr.notifyManager = notify.NewManager(cr.dataDir, cr.database, cr.client, config.Dashboard.NotifySubject)
- // Add notification plugins
- webpushPlg := new(webpush.Plugin)
- cr.notifyManager.AddPlugin(webpushPlg)
- if config.Notification.EnableEmail {
- emailPlg, err := email.NewSMTP(
- config.Notification.EmailSMTP, config.Notification.EmailSMTPEncryption,
- config.Notification.EmailSender, config.Notification.EmailSenderPassword,
- )
- if err != nil {
- return err
- }
- cr.notifyManager.AddPlugin(emailPlg)
- }
-
- if err = cr.notifyManager.Init(ctx); err != nil {
- return
- }
- cr.webpushKeyB64 = base64.RawURLEncoding.EncodeToString(webpushPlg.GetPublicKey())
-
- // Init storages
- vctx := context.WithValue(ctx, storage.ClusterCacheCtxKey, cr.cache)
- for _, s := range cr.storages {
- s.Init(vctx)
- }
-
- // read old stats
- if err := cr.stats.Load(cr.dataDir); err != nil {
- log.Errorf("Could not load stats: %v", err)
- }
- if cr.apiHmacKey, err = utils.LoadOrCreateHmacKey(cr.dataDir); err != nil {
- return fmt.Errorf("Cannot load hmac key: %w", err)
- }
-
- cr.updateChecker = time.NewTicker(time.Hour)
-
- go func(ticker *time.Ticker) {
- defer log.RecoverPanic(nil)
- defer ticker.Stop()
-
- if err := cr.checkUpdate(); err != nil {
- log.Errorf(Tr("error.update.check.failed"), err)
- }
- for range ticker.C {
- if err := cr.checkUpdate(); err != nil {
- log.Errorf(Tr("error.update.check.failed"), err)
- }
- }
- }(cr.updateChecker)
- return
-}
-
-func (cr *Cluster) Destroy(ctx context.Context) {
- if cr.database != nil {
- cr.database.Cleanup()
- }
- cr.updateChecker.Stop()
- if cr.apiRateLimiter != nil {
- cr.apiRateLimiter.Destroy()
- }
-}
-
-func (cr *Cluster) allocBuf(ctx context.Context) (slotId int, buf []byte, free func()) {
- return cr.bufSlots.Alloc(ctx)
-}
-
-func (cr *Cluster) Connect(ctx context.Context) bool {
- cr.mux.Lock()
- defer cr.mux.Unlock()
-
- if cr.socket != nil {
- log.Debug("Extra connect")
- return true
- }
-
- _, err := cr.GetAuthToken(ctx)
- if err != nil {
- log.Errorf(Tr("error.cluster.auth.failed"), err)
- osExit(CodeClientOrServerError)
- }
-
- engio, err := engine.NewSocket(engine.Options{
- Host: cr.prefix,
- Path: "/socket.io/",
- ExtraHeaders: http.Header{
- "Origin": {cr.prefix},
- "User-Agent": {build.ClusterUserAgent},
- },
- DialTimeout: time.Minute * 6,
- })
- if err != nil {
- log.Errorf("Could not parse Engine.IO options: %v; exit.", err)
- osExit(CodeClientUnexpectedError)
- }
-
- cr.reconnectCount = 0
- connected := false
-
- if config.Advanced.SocketIOLog {
- engio.OnRecv(func(_ *engine.Socket, data []byte) {
- log.Debugf("Engine.IO recv: %q", (string)(data))
- })
- engio.OnSend(func(_ *engine.Socket, data []byte) {
- log.Debugf("Engine.IO sending: %q", (string)(data))
- })
- }
- engio.OnConnect(func(*engine.Socket) {
- log.Info("Engine.IO connected")
- })
- engio.OnDisconnect(func(_ *engine.Socket, err error) {
- if ctx.Err() != nil {
- // Ignore if the error is because context cancelled
- return
- }
- if err != nil {
- log.Warnf("Engine.IO disconnected: %v", err)
- }
- if config.MaxReconnectCount == 0 {
- if cr.shouldEnable.Load() {
- log.Errorf("Cluster disconnected from remote; exit.")
- osExit(CodeServerOrEnvionmentError)
- }
- }
- if !connected {
- cr.reconnectCount++
- if config.MaxReconnectCount > 0 && cr.reconnectCount >= config.MaxReconnectCount {
- if cr.shouldEnable.Load() {
- log.Error(Tr("error.cluster.connect.failed.toomuch"))
- osExit(CodeServerOrEnvionmentError)
- }
- }
- }
- connected = false
- go cr.disconnected()
- })
- engio.OnDialError(func(_ *engine.Socket, err error) {
- cr.reconnectCount++
- log.Errorf(Tr("error.cluster.connect.failed"), cr.reconnectCount, config.MaxReconnectCount, err)
- if config.MaxReconnectCount >= 0 && cr.reconnectCount >= config.MaxReconnectCount {
- if cr.shouldEnable.Load() {
- log.Error(Tr("error.cluster.connect.failed.toomuch"))
- osExit(CodeServerOrEnvionmentError)
- }
- }
- })
-
- cr.socket = socket.NewSocket(engio, socket.WithAuthTokenFn(func() string {
- token, err := cr.GetAuthToken(ctx)
- if err != nil {
- log.Errorf(Tr("error.cluster.auth.failed"), err)
- osExit(CodeServerOrEnvionmentError)
- }
- return token
- }))
- cr.socket.OnBeforeConnect(func(*socket.Socket) {
- log.Infof(Tr("info.cluster.connect.prepare"), cr.reconnectCount, config.MaxReconnectCount)
- })
- cr.socket.OnConnect(func(*socket.Socket, string) {
- connected = true
- log.Debugf("shouldEnable is %v", cr.shouldEnable.Load())
- if cr.shouldEnable.Load() {
- if err := cr.Enable(ctx); err != nil {
- log.Errorf(Tr("error.cluster.enable.failed"), err)
- osExit(CodeClientOrEnvionmentError)
- }
- }
- })
- cr.socket.OnDisconnect(func(*socket.Socket, string) {
- go cr.disconnected()
- })
- cr.socket.OnError(func(_ *socket.Socket, err error) {
- if ctx.Err() != nil {
- // Ignore if the error is because context cancelled
- return
- }
- log.Errorf("Socket.IO error: %v", err)
- })
- cr.socket.OnMessage(func(event string, data []any) {
- if event == "message" {
- log.Infof("[remote]: %v", data[0])
- }
- })
- log.Infof("Dialing %s", engio.URL().String())
- if err := engio.Dial(ctx); err != nil {
- log.Errorf("Dial error: %v", err)
- return false
- }
- log.Info("Connecting to socket.io namespace")
- if err := cr.socket.Connect(""); err != nil {
- log.Errorf("Open namespace error: %v", err)
- return false
- }
- return true
-}
-
-func (cr *Cluster) WaitForEnable() <-chan struct{} {
- if cr.enabled.Load() {
- return closedCh
- }
-
- cr.mux.Lock()
- defer cr.mux.Unlock()
-
- if cr.enabled.Load() {
- return closedCh
- }
- ch := make(chan struct{}, 0)
- cr.waitEnable = append(cr.waitEnable, ch)
- return ch
-}
-
-type EnableData struct {
- Host string `json:"host"`
- Port uint16 `json:"port"`
- Version string `json:"version"`
- Byoc bool `json:"byoc"`
- NoFastEnable bool `json:"noFastEnable"`
- Flavor ConfigFlavor `json:"flavor"`
-}
-
-type ConfigFlavor struct {
- Runtime string `json:"runtime"`
- Storage string `json:"storage"`
-}
-
-func (cr *Cluster) Enable(ctx context.Context) (err error) {
- cr.mux.Lock()
- defer cr.mux.Unlock()
-
- if cr.enabled.Load() {
- log.Debug("Extra enable")
- return
- }
-
- if cr.socket != nil && !cr.socket.IO().Connected() && config.MaxReconnectCount == 0 {
- log.Error(Tr("error.cluster.disconnected"))
- osExit(CodeServerOrEnvionmentError)
- return
- }
-
- cr.shouldEnable.Store(true)
-
- storagesCount := make(map[string]int, 2)
- for _, s := range cr.storageOpts {
- switch s.Type {
- case storage.StorageLocal:
- storagesCount["file"]++
- case storage.StorageMount, storage.StorageWebdav:
- storagesCount["alist"]++
- default:
- log.Errorf("Unknown storage type %q", s.Type)
- }
- }
- storageStr := ""
- for s, _ := range storagesCount {
- if len(storageStr) > 0 {
- storageStr += "+"
- }
- storageStr += s
- }
-
- log.Info(Tr("info.cluster.enable.sending"))
- resCh, err := cr.socket.EmitWithAck("enable", EnableData{
- Host: cr.host,
- Port: cr.publicPort,
- Version: build.ClusterVersion,
- Byoc: cr.byoc,
- NoFastEnable: config.Advanced.NoFastEnable,
- Flavor: ConfigFlavor{
- Runtime: "golang/" + runtime.GOOS + "-" + runtime.GOARCH,
- Storage: storageStr,
- },
- })
- if err != nil {
- return
- }
- var data []any
- tctx, cancel := context.WithTimeout(ctx, time.Minute*6)
- select {
- case <-tctx.Done():
- cancel()
- return tctx.Err()
- case data = <-resCh:
- cancel()
- }
- log.Debug("got enable ack:", data)
- if ero := data[0]; ero != nil {
- if ero, ok := ero.(map[string]any); ok {
- if msg, ok := ero["message"].(string); ok {
- if hashMismatch := reFileHashMismatchError.FindStringSubmatch(msg); hashMismatch != nil {
- hash := hashMismatch[1]
- log.Warnf("Detected hash mismatch error, removing bad file %s", hash)
- for _, s := range cr.storages {
- s.Remove(hash)
- }
- }
- return fmt.Errorf("Enable failed: %v", msg)
- }
- }
- return fmt.Errorf("Enable failed: %v", ero)
- }
- if !data[1].(bool) {
- return errors.New("Enable ack non true value")
- }
- log.Info(Tr("info.cluster.enabled"))
- cr.reconnectCount = 0
- cr.disabled = make(chan struct{}, 0)
- cr.enabled.Store(true)
- for _, ch := range cr.waitEnable {
- close(ch)
- }
- cr.waitEnable = cr.waitEnable[:0]
- go cr.notifyManager.OnEnabled()
-
- const maxFailCount = 3
- var (
- keepaliveCtx context.Context
- failedCount = 0
- )
- keepaliveCtx, cr.cancelKeepalive = context.WithCancel(ctx)
- createInterval(keepaliveCtx, func() {
- tctx, cancel := context.WithTimeout(keepaliveCtx, KeepAliveInterval/2)
- status := cr.KeepAlive(tctx)
- cancel()
- if status == 0 {
- failedCount = 0
- return
- }
- if status == -1 {
- log.Errorf("Kicked by remote server!!!")
- osExit(CodeEnvironmentError)
- return
- }
- if keepaliveCtx.Err() == nil {
- if tctx.Err() != nil {
- failedCount++
- log.Warnf("keep-alive failed (%d/%d)", failedCount, maxFailCount)
- if failedCount < maxFailCount {
- return
- }
- }
- log.Info(Tr("info.cluster.reconnect.keepalive"))
- cr.disable(ctx)
- log.Info(Tr("info.cluster.reconnecting"))
- if !cr.Connect(ctx) {
- log.Error(Tr("error.cluster.reconnect.failed"))
- if ctx.Err() != nil {
- return
- }
- osExit(CodeServerOrEnvionmentError)
- }
- if err := cr.Enable(ctx); err != nil {
- log.Errorf(Tr("error.cluster.enable.failed"), err)
- if ctx.Err() != nil {
- return
- }
- osExit(CodeClientOrEnvionmentError)
- }
- }
- }, KeepAliveInterval)
- return
-}
-
-// KeepAlive will fresh hits & hit bytes data and send the keep-alive packet
-func (cr *Cluster) KeepAlive(ctx context.Context) (status int) {
- hits, hbts := cr.stats.GetTmpHits()
- lhits, lhbts := cr.lastHits.Load(), cr.lastHbts.Load()
- hits2, hbts2 := cr.statOnlyHits.Load(), cr.statOnlyHbts.Load()
- ahits, ahbts := hits-lhits-hits2, hbts-lhbts-hbts2
- resCh, err := cr.socket.EmitWithAck("keep-alive", Map{
- "time": time.Now().UTC().Format("2006-01-02T15:04:05Z"),
- "hits": ahits,
- "bytes": ahbts,
- })
- go cr.notifyManager.OnReportStatus(&cr.stats)
-
- if e := cr.stats.Save(cr.dataDir); e != nil {
- log.Errorf(Tr("error.cluster.stat.save.failed"), e)
- }
- if err != nil {
- log.Errorf(Tr("error.cluster.keepalive.send.failed"), err)
- return 1
- }
- var data []any
- select {
- case <-ctx.Done():
- return 1
- case data = <-resCh:
- }
- log.Debugf("Keep-alive response: %v", data)
- if ero := data[0]; len(data) <= 1 || ero != nil {
- if ero, ok := ero.(map[string]any); ok {
- if msg, ok := ero["message"].(string); ok {
- if hashMismatch := reFileHashMismatchError.FindStringSubmatch(msg); hashMismatch != nil {
- hash := hashMismatch[1]
- log.Warnf("Detected hash mismatch error, removing bad file %s", hash)
- for _, s := range cr.storages {
- s.Remove(hash)
- }
- }
- log.Errorf(Tr("error.cluster.keepalive.failed"), msg)
- return 1
- }
- }
- log.Errorf(Tr("error.cluster.keepalive.failed"), ero)
- return 1
- }
- log.Infof(Tr("info.cluster.keepalive.success"), ahits, utils.BytesToUnit((float64)(ahbts)), data[1])
- cr.lastHits.Store(hits)
- cr.lastHbts.Store(hbts)
- cr.statOnlyHits.Add(-hits2)
- cr.statOnlyHbts.Add(-hbts2)
- if data[1] == false {
- return -1
- }
- return 0
-}
-
-func (cr *Cluster) disconnected() bool {
- cr.mux.Lock()
- defer cr.mux.Unlock()
-
- if cr.enabled.CompareAndSwap(true, false) {
- return false
- }
- if cr.cancelKeepalive != nil {
- cr.cancelKeepalive()
- cr.cancelKeepalive = nil
- }
- cr.notifyManager.OnDisabled()
- return true
-}
-
-func (cr *Cluster) Disable(ctx context.Context) (ok bool) {
- cr.shouldEnable.Store(false)
- return cr.disable(ctx)
-}
-
-func (cr *Cluster) disable(ctx context.Context) (ok bool) {
- cr.mux.Lock()
- defer cr.mux.Unlock()
-
- if !cr.enabled.Load() {
- log.Debug("Extra disable")
- return false
- }
-
- defer cr.notifyManager.OnDisabled()
-
- if cr.cancelKeepalive != nil {
- cr.cancelKeepalive()
- cr.cancelKeepalive = nil
- }
- if cr.socket == nil {
- return false
- }
- log.Info(Tr("info.cluster.disabling"))
- resCh, err := cr.socket.EmitWithAck("disable", nil)
- if err == nil {
- tctx, cancel := context.WithTimeout(ctx, time.Second*(time.Duration)(config.Advanced.KeepaliveTimeout))
- select {
- case <-tctx.Done():
- cancel()
- err = tctx.Err()
- case data := <-resCh:
- cancel()
- log.Debug("disable ack:", data)
- if ero := data[0]; ero != nil {
- log.Errorf("Disable failed: %v", ero)
- } else if !data[1].(bool) {
- log.Error("Disable failed: acked non true value")
- } else {
- ok = true
- }
- }
- }
- if err != nil {
- log.Errorf(Tr("error.cluster.disable.failed"), err)
- }
-
- cr.enabled.Store(false)
- go cr.socket.Close()
- cr.socket = nil
- close(cr.disabled)
- log.Warn(Tr("warn.cluster.disabled"))
- return
-}
-
-func (cr *Cluster) Enabled() bool {
- return cr.enabled.Load()
-}
-
-func (cr *Cluster) Disabled() <-chan struct{} {
- cr.mux.RLock()
- defer cr.mux.RUnlock()
- return cr.disabled
-}
-
-type CertKeyPair struct {
- Cert string `json:"cert"`
- Key string `json:"key"`
-}
-
-func (cr *Cluster) RequestCert(ctx context.Context) (ckp *CertKeyPair, err error) {
- resCh, err := cr.socket.EmitWithAck("request-cert")
- if err != nil {
- return
- }
- var data []any
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- case data = <-resCh:
- }
- if ero := data[0]; ero != nil {
- err = fmt.Errorf("socket.io remote error: %v", ero)
- return
- }
- pair := data[1].(map[string]any)
- ckp = &CertKeyPair{
- Cert: pair["cert"].(string),
- Key: pair["key"].(string),
- }
- return
-}
-
-func (cr *Cluster) GetConfig(ctx context.Context) (cfg *OpenbmclapiAgentConfig, err error) {
- req, err := cr.makeReqWithAuth(ctx, http.MethodGet, "/openbmclapi/configuration", nil)
- if err != nil {
- return
- }
- res, err := cr.cachedCli.Do(req)
- if err != nil {
- return
- }
- defer res.Body.Close()
- if res.StatusCode != http.StatusOK {
- err = utils.NewHTTPStatusErrorFromResponse(res)
- return
- }
- cfg = new(OpenbmclapiAgentConfig)
- if err = json.NewDecoder(res.Body).Decode(cfg); err != nil {
- cfg = nil
- return
- }
- return
-}
diff --git a/cluster/cluster.go b/cluster/cluster.go
new file mode 100644
index 00000000..35d7df4b
--- /dev/null
+++ b/cluster/cluster.go
@@ -0,0 +1,389 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/LiterMC/socket.io"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/config"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/storage"
+)
+
+var (
+ reFileHashMismatchError = regexp.MustCompile(` hash mismatch, expected ([0-9a-f]+), got ([0-9a-f]+)`)
+)
+
+const DefaultBMCLAPIServer = "https://openbmclapi.bangbang93.com"
+
+type Cluster struct {
+ name string
+ opts config.ClusterOptions
+ gcfg config.ClusterGeneralConfig
+
+ storageManager *storage.Manager
+ storages []int // the index of storages in the storage manager
+ statManager *StatManager
+
+ enableSignals []chan bool
+ disableSignal chan struct{}
+ hits atomic.Int32
+ hbts atomic.Int64
+
+ mux sync.RWMutex
+ status atomic.Int32
+ shouldEnable atomic.Bool
+ socket *socket.Socket
+ client *HTTPClient
+
+ authTokenMux sync.RWMutex
+ authToken *ClusterToken
+ fileListLastMod int64
+}
+
+var _ api.Cluster = (*Cluster)(nil)
+
+func NewCluster(
+ name string, opts config.ClusterOptions, gcfg config.ClusterGeneralConfig,
+ storageManager *storage.Manager,
+ statManager *StatManager,
+ client *HTTPClient,
+) (cr *Cluster) {
+ storages := make([]int, len(opts.Storages))
+ for i, name := range opts.Storages {
+ storages[i] = storageManager.GetIndex(name)
+ }
+ if opts.Server == "" {
+ opts.Server = DefaultBMCLAPIServer
+ }
+ cr = &Cluster{
+ name: name,
+ opts: opts,
+ gcfg: gcfg,
+
+ storageManager: storageManager,
+ storages: storages,
+ statManager: statManager,
+ client: client,
+ }
+ return
+}
+
+// ID returns the cluster id
+// The ID may not be unique in the OpenBMCLAPI cluster runtime.
+// To identify the cluster instance for analyzing, use Name instead.
+func (cr *Cluster) ID() string {
+ return cr.opts.Id
+}
+
+// Name returns the cluster's alias name
+// The name must be unique in the OpenBMCLAPI cluster runtime.
+func (cr *Cluster) Name() string {
+ return cr.name
+}
+
+// Secret returns the cluster secret
+func (cr *Cluster) Secret() string {
+ return cr.opts.Secret
+}
+
+// Host returns the cluster public host
+func (cr *Cluster) Host() string {
+ return cr.gcfg.PublicHost
+}
+
+// Port returns the cluster public port
+func (cr *Cluster) Port() uint16 {
+ return cr.gcfg.PublicPort
+}
+
+// PublicHosts returns the cluster public hosts
+func (cr *Cluster) PublicHosts() []string {
+ return cr.opts.PublicHosts
+}
+
+// AcceptHost checks if the host is binded to the cluster
+func (cr *Cluster) AcceptHost(host string) bool {
+ host = strings.ToUpper(host)
+ for _, h := range cr.opts.PublicHosts {
+ if h == "*" || strings.ToUpper(h) == host {
+ return true
+ }
+ }
+ return false
+}
+
+func (cr *Cluster) Options() *config.ClusterOptions {
+ return &cr.opts
+}
+
+func (cr *Cluster) GeneralConfig() *config.ClusterGeneralConfig {
+ return &cr.gcfg
+}
+
+// Init do setup on the cluster
+// Init should only be called once during the cluster's whole life
+// The context passed in only affect the logical of Init method
+func (cr *Cluster) Init(ctx context.Context) error {
+ for i, ind := range cr.storages {
+ if ind == -1 {
+ return fmt.Errorf("Storage %q does not exists", cr.opts.Storages[i])
+ }
+ }
+ return nil
+}
+
+type EnableData struct {
+ Host string `json:"host"`
+ Port uint16 `json:"port"`
+ Version string `json:"version"`
+ Byoc bool `json:"byoc"`
+ NoFastEnable bool `json:"noFastEnable"`
+ Flavor ConfigFlavor `json:"flavor"`
+}
+
+type ConfigFlavor struct {
+ Runtime string `json:"runtime"`
+ Storage string `json:"storage"`
+}
+
+// Enable send enable packet to central server
+// The context passed in only affect the logical of Enable method
+func (cr *Cluster) Enable(ctx context.Context) error {
+ if cr.Status() == api.ClusterEnabled {
+ return nil
+ }
+
+ cr.mux.Lock()
+ defer cr.mux.Unlock()
+
+ if !cr.status.CompareAndSwap(api.ClusterDisabled, api.ClusterEnabling) {
+ return nil
+ }
+
+ if err := cr.enable(ctx); err != nil {
+ cr.status.Store(api.ClusterDisabled)
+ return err
+ }
+
+ enabled := cr.Status().Running()
+ for _, ch := range cr.enableSignals {
+ ch <- enabled
+ }
+ cr.enableSignals = cr.enableSignals[:0]
+ return nil
+}
+
+type enableError struct {
+ Err any
+}
+
+func (e *enableError) Error() string {
+ return fmt.Sprintf("Enable Failed: %v", e.Err)
+}
+
+func (cr *Cluster) enable(ctx context.Context) error {
+ storageStr := cr.storageManager.GetFlavorString(cr.storages)
+
+ log.TrInfof("info.cluster.enable.sending")
+ resCh, err := cr.socket.EmitWithAck("enable", EnableData{
+ Host: cr.gcfg.PublicHost,
+ Port: cr.gcfg.PublicPort,
+ Version: build.ClusterVersion,
+ Byoc: cr.opts.Byoc,
+ NoFastEnable: cr.gcfg.NoFastEnable,
+ Flavor: ConfigFlavor{
+ Runtime: "golang/" + runtime.GOOS + "-" + runtime.GOARCH,
+ Storage: storageStr,
+ },
+ })
+ if err != nil {
+ return err
+ }
+ var data []any
+ {
+ tctx, cancel := context.WithTimeout(ctx, time.Minute*6)
+ select {
+ case data = <-resCh:
+ cancel()
+ case <-tctx.Done():
+ cancel()
+ return tctx.Err()
+ }
+ }
+ log.Debug("got enable ack:", data)
+ if ero := data[0]; ero != nil {
+ if ero, ok := ero.(map[string]any); ok {
+ if msg, ok := ero["message"].(string); ok {
+ if hashMismatch := reFileHashMismatchError.FindStringSubmatch(msg); hashMismatch != nil {
+ hash := hashMismatch[1]
+ log.TrWarnf("warn.cluster.detected.hash.mismatch", hash)
+ cr.storageManager.RemoveForAll(hash)
+ }
+ return &enableError{msg}
+ }
+ }
+ return &enableError{ero}
+ }
+ if v := data[1]; !v.(bool) {
+ return fmt.Errorf("FATAL: Enable acked non true value, got (%T) %#v", v, v)
+ }
+ disableSignal := make(chan struct{}, 0)
+ cr.disableSignal = disableSignal
+ log.TrInfof("info.cluster.enabled")
+ cr.status.Store(api.ClusterEnabled)
+ cr.socket.OnceConnect(func(_ *socket.Socket, ns string) {
+ if ns != "" {
+ return
+ }
+ cr.status.Store(api.ClusterDisabled)
+ if !cr.shouldEnable.Load() {
+ return
+ }
+ select {
+ case <-disableSignal:
+ return
+ default:
+ }
+ go cr.reEnable(disableSignal)
+ })
+ cr.socket.OnceDisconnect(func(_ *socket.Socket, ns string) {
+ if ns != "" {
+ return
+ }
+ cr.status.Store(api.ClusterDisconnected)
+ })
+ return nil
+}
+
+func (cr *Cluster) reEnable(disableSignal <-chan struct{}) {
+ const ReEnableTimeout = time.Minute * 5
+
+ if !cr.status.CompareAndSwap(api.ClusterDisabled, api.ClusterEnabling) {
+ return
+ }
+ tctx, cancel := context.WithTimeout(context.Background(), ReEnableTimeout)
+ go func() {
+ select {
+ case <-tctx.Done():
+ case <-disableSignal:
+ cancel()
+ }
+ }()
+ err := cr.enable(tctx)
+ cancel()
+ if err == nil {
+ return
+ }
+ log.TrErrorf("error.cluster.enable.failed", err)
+ if cr.Status() != api.ClusterEnabled {
+ return
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+ timer := time.AfterFunc(time.Minute, func() {
+ cancel()
+ cr.reEnable(disableSignal)
+ })
+ go func() {
+ select {
+ case <-ctx.Done():
+ case <-disableSignal:
+ timer.Stop()
+ cancel()
+ }
+ }()
+}
+
+// Disable send disable packet to central server
+// The context passed in only affect the logical of Disable method
+// Disable method is thread-safe, and it will wait until the first invoke exited
+// Connection will not be closed after disable
+func (cr *Cluster) Disable(ctx context.Context) error {
+ if cr.Status().Enabled() {
+ cr.mux.Lock()
+ defer cr.mux.Unlock()
+ if cr.Status().Enabled() {
+ defer close(cr.disableSignal)
+ defer cr.status.Store(api.ClusterDisabled)
+ return cr.disable(ctx)
+ }
+ }
+ // sync disable
+ cr.mux.RLock()
+ disableCh := cr.disableSignal
+ cr.mux.RUnlock()
+ if disableCh == nil {
+ return nil
+ }
+ select {
+ case <-disableCh:
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ return nil
+}
+
+// disable send disable packet to central server
+// The context passed in only affect the logical of disable method
+func (cr *Cluster) disable(ctx context.Context) error {
+ log.TrInfof("info.cluster.disabling")
+ resCh, err := cr.socket.EmitWithAck("disable", nil)
+ if err != nil {
+ return err
+ }
+ select {
+ case data := <-resCh:
+ log.Debug("disable ack:", data)
+ if ero := data[0]; ero != nil {
+ return fmt.Errorf("Disable failed: %v", ero)
+ } else if !data[1].(bool) {
+ return errors.New("Disable acked non true value")
+ }
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ return nil
+}
+
+// markKicked marks the cluster as kicked
+func (cr *Cluster) markKicked() {
+ if !cr.Status().Enabled() {
+ return
+ }
+ cr.mux.Lock()
+ defer cr.mux.Unlock()
+ if cr.Status().Enabled() {
+ return
+ }
+ defer close(cr.disableSignal)
+ cr.status.Store(api.ClusterDisabled)
+}
diff --git a/cluster/handler.go b/cluster/handler.go
new file mode 100644
index 00000000..118f6d12
--- /dev/null
+++ b/cluster/handler.go
@@ -0,0 +1,209 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "crypto"
+ "encoding/base64"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "net/http"
+ "net/textproto"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/storage"
+)
+
+func (cr *Cluster) HandleFile(rw http.ResponseWriter, req *http.Request, hash string) {
+ defer log.RecoverPanic(nil)
+
+ if !cr.Status().Enabled() {
+ // do not serve file if cluster is not enabled yet
+ http.Error(rw, "Cluster is not enabled yet", http.StatusServiceUnavailable)
+ return
+ }
+
+ if !cr.checkQuerySign(req, hash) {
+ http.Error(rw, "Cannot verify signature", http.StatusForbidden)
+ return
+ }
+
+ log.Debugf("Handling download %s", hash)
+
+ keepaliveRec := req.Context().Value("go-openbmclapi.handler.no.record.for.keepalive") != true
+
+ countUA := true
+ if r := req.Header.Get("Range"); r != "" {
+ api.SetAccessInfo(req, "range", r)
+ if start, ok := parseRangeFirstStart(r); ok && start != 0 {
+ countUA = false
+ }
+ }
+ ua := ""
+ if countUA {
+ ua, _, _ = strings.Cut(req.UserAgent(), " ")
+ ua, _, _ = strings.Cut(ua, "/")
+ }
+
+ rw.Header().Set("X-Bmclapi-Hash", hash)
+
+ if _, ok := emptyHashes[hash]; ok {
+ name := req.URL.Query().Get("name")
+ rw.Header().Set("ETag", `"`+hash+`"`)
+ rw.Header().Set("Cache-Control", "public, max-age=31536000, immutable") // cache for a year
+ rw.Header().Set("Content-Type", "application/octet-stream")
+ rw.Header().Set("Content-Length", "0")
+ if name != "" {
+ rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", name))
+ }
+ rw.WriteHeader(http.StatusOK)
+ cr.statManager.AddHit(0, cr.ID(), "", ua)
+ if keepaliveRec {
+ cr.hits.Add(1)
+ }
+ return
+ }
+
+ api.SetAccessInfo(req, "cluster", cr.ID())
+
+ var size int64 = -1 // TODO: get the size
+
+ var (
+ sto storage.Storage
+ err error
+ )
+ ok := cr.storageManager.ForEachFromRandom(cr.storages, func(s storage.Storage) bool {
+ sto = s
+ opts := s.Options()
+ log.Debugf("[handler]: Checking %s on storage %s ...", hash, opts.Id)
+
+ sz, er := s.ServeDownload(rw, req, hash, size)
+ if er != nil {
+ log.Debugf("[handler]: File %s failed on storage %s: %v", hash, opts.Id, er)
+ err = er
+ return false
+ }
+ if sz >= 0 {
+ if keepaliveRec {
+ cr.hits.Add(1)
+ cr.hbts.Add(sz)
+ }
+ cr.statManager.AddHit(sz, cr.ID(), opts.Id, ua)
+ }
+ return true
+ })
+ if sto != nil {
+ api.SetAccessInfo(req, "storage", sto.Id())
+ }
+ if ok {
+ return
+ }
+ http.Error(rw, err.Error(), http.StatusInternalServerError)
+}
+
+func (cr *Cluster) HandleMeasure(rw http.ResponseWriter, req *http.Request, size int) {
+ if !cr.Status().Enabled() {
+ // do not serve file if cluster is not enabled yet
+ http.Error(rw, "Cluster is not enabled yet", http.StatusServiceUnavailable)
+ return
+ }
+
+ if !cr.checkQuerySign(req, req.URL.Path) {
+ http.Error(rw, "Cannot verify signature", http.StatusForbidden)
+ return
+ }
+
+ api.SetAccessInfo(req, "cluster", cr.ID())
+ storage := cr.storageManager.Storages[cr.storages[0]]
+ api.SetAccessInfo(req, "storage", storage.Id())
+ if err := storage.ServeMeasure(rw, req, size); err != nil {
+ log.Errorf("Could not serve measure %d: %v", size, err)
+ api.SetAccessInfo(req, "error", err.Error())
+ http.Error(rw, err.Error(), http.StatusInternalServerError)
+ }
+}
+
+func (cr *Cluster) checkQuerySign(req *http.Request, hash string) bool {
+ if cr.opts.SkipSignatureCheck {
+ return true
+ }
+ query := req.URL.Query()
+ sign, e := query.Get("s"), query.Get("e")
+ if len(sign) == 0 || len(e) == 0 {
+ return false
+ }
+ before, err := strconv.ParseInt(e, 36, 64)
+ if err != nil {
+ return false
+ }
+ if time.Now().UnixMilli() > before {
+ return false
+ }
+ hs := crypto.SHA1.New()
+ io.WriteString(hs, cr.Secret())
+ io.WriteString(hs, hash)
+ io.WriteString(hs, e)
+ var (
+ buf [20]byte
+ sbuf [27]byte
+ )
+ base64.RawURLEncoding.Encode(sbuf[:], hs.Sum(buf[:0]))
+ if (string)(sbuf[:]) != sign {
+ return false
+ }
+ return true
+}
+
+var emptyHashes = func() (hashes map[string]struct{}) {
+ hashMethods := []crypto.Hash{
+ crypto.MD5, crypto.SHA1,
+ }
+ hashes = make(map[string]struct{}, len(hashMethods))
+ for _, h := range hashMethods {
+ hs := hex.EncodeToString(h.New().Sum(nil))
+ hashes[hs] = struct{}{}
+ }
+ return
+}()
+
+// Note: this method is a fast parse, it does not deeply check if the range is valid or not
+func parseRangeFirstStart(rg string) (start int64, ok bool) {
+ const b = "bytes="
+ if rg, ok = strings.CutPrefix(rg, b); !ok {
+ return
+ }
+ rg, _, _ = strings.Cut(rg, ",")
+ if rg, _, ok = strings.Cut(rg, "-"); !ok {
+ return
+ }
+ if rg = textproto.TrimString(rg); rg == "" {
+ return -1, true
+ }
+ start, err := strconv.ParseInt(rg, 10, 64)
+ if err != nil {
+ return 0, false
+ }
+ return start, true
+}
diff --git a/cluster/http.go b/cluster/http.go
new file mode 100644
index 00000000..4f16136b
--- /dev/null
+++ b/cluster/http.go
@@ -0,0 +1,146 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "context"
+ "errors"
+ "io"
+ "net"
+ "net/http"
+ "net/url"
+ "path"
+
+ "github.com/gregjones/httpcache"
+
+ gocache "github.com/LiterMC/go-openbmclapi/cache"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type HTTPClient struct {
+ cli, cachedCli *http.Client
+}
+
+func NewHTTPClient(dialer *net.Dialer, cache gocache.Cache) *HTTPClient {
+ transport := http.DefaultTransport
+ if dialer != nil {
+ transport = &http.Transport{
+ DialContext: dialer.DialContext,
+ }
+ }
+ transport = utils.NewRoundTripRedirectErrorWrapper(transport)
+ cachedTransport := transport
+ if cache != gocache.NoCache {
+ cachedTransport = &httpcache.Transport{
+ Transport: transport,
+ Cache: gocache.WrapToHTTPCache(gocache.NewCacheWithNamespace(cache, "http@")),
+ }
+ }
+ return &HTTPClient{
+ cli: &http.Client{
+ Transport: transport,
+ CheckRedirect: redirectChecker,
+ },
+ cachedCli: &http.Client{
+ Transport: cachedTransport,
+ CheckRedirect: redirectChecker,
+ },
+ }
+}
+
+func (c *HTTPClient) Do(req *http.Request) (*http.Response, error) {
+ return c.cli.Do(req)
+}
+
+func (c *HTTPClient) DoUseCache(req *http.Request) (*http.Response, error) {
+ return c.cachedCli.Do(req)
+}
+
+func (c *HTTPClient) Client() *http.Client {
+ return c.cli
+}
+
+func (c *HTTPClient) CachedClient() *http.Client {
+ return c.cachedCli
+}
+
+func redirectChecker(req *http.Request, via []*http.Request) error {
+ req.Header.Del("Referer")
+ if len(via) > 10 {
+ return errors.New("More than 10 redirects detected")
+ }
+ return nil
+}
+
+func (cr *Cluster) getFullURL(relpath string) (u *url.URL, err error) {
+ if u, err = url.Parse(cr.opts.Server); err != nil {
+ return
+ }
+ u.Path = path.Join(u.Path, relpath)
+ return
+}
+
+func (cr *Cluster) makeReq(ctx context.Context, method string, relpath string, query url.Values) (req *http.Request, err error) {
+ return cr.makeReqWithBody(ctx, method, relpath, query, nil)
+}
+
+func (cr *Cluster) makeReqWithBody(
+ ctx context.Context,
+ method string, relpath string,
+ query url.Values, body io.Reader,
+) (req *http.Request, err error) {
+ u, err := cr.getFullURL(relpath)
+ if err != nil {
+ return
+ }
+ if query != nil {
+ u.RawQuery = query.Encode()
+ }
+ target := u.String()
+
+ req, err = http.NewRequestWithContext(ctx, method, target, body)
+ if err != nil {
+ return
+ }
+ req.Header.Set("User-Agent", build.ClusterUserAgent)
+ return
+}
+
+func (cr *Cluster) makeReqWithAuth(ctx context.Context, method string, relpath string, query url.Values) (req *http.Request, err error) {
+ return cr.makeReqWithAuthBody(ctx, method, relpath, query, nil)
+}
+
+func (cr *Cluster) makeReqWithAuthBody(
+ ctx context.Context,
+ method string, relpath string,
+ query url.Values, body io.Reader,
+) (req *http.Request, err error) {
+ req, err = cr.makeReqWithBody(ctx, method, relpath, query, body)
+ if err != nil {
+ return
+ }
+ token, err := cr.GetAuthToken(ctx)
+ if err != nil {
+ return
+ }
+ req.Header.Set("Authorization", "Bearer "+token)
+ return
+}
diff --git a/cluster/keepalive.go b/cluster/keepalive.go
new file mode 100644
index 00000000..78fc2eef
--- /dev/null
+++ b/cluster/keepalive.go
@@ -0,0 +1,87 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "context"
+ "time"
+
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type KeepAliveRes int
+
+const (
+ KeepAliveSucceed KeepAliveRes = iota
+ KeepAliveFailed
+ KeepAliveKicked
+)
+
+type keepAliveReq struct {
+ Time string `json:"time"`
+ Hits int32 `json:"hits"`
+ Bytes int64 `json:"bytes"`
+}
+
+// KeepAlive will send the keep-alive packet and fresh hits & hit bytes data
+// If cluster is kicked by the central server, the cluster status will be mark as kicked
+func (cr *Cluster) KeepAlive(ctx context.Context) KeepAliveRes {
+ hits, hbts := cr.hits.Load(), cr.hbts.Load()
+ resCh, err := cr.socket.EmitWithAck("keep-alive", keepAliveReq{
+ Time: time.Now().UTC().Format("2006-01-02T15:04:05Z"),
+ Hits: hits,
+ Bytes: hbts,
+ })
+ if err != nil {
+ log.TrErrorf("error.cluster.keepalive.send.failed", err)
+ return KeepAliveFailed
+ }
+ var data []any
+ select {
+ case <-ctx.Done():
+ return KeepAliveFailed
+ case data = <-resCh:
+ }
+ log.Debugf("Keep-alive response: %v", data)
+ if ero := data[0]; len(data) <= 1 || ero != nil {
+ if ero, ok := ero.(map[string]any); ok {
+ if msg, ok := ero["message"].(string); ok {
+ log.TrErrorf("error.cluster.keepalive.failed", msg)
+ if hashMismatch := reFileHashMismatchError.FindStringSubmatch(msg); hashMismatch != nil {
+ hash := hashMismatch[1]
+ log.Warnf("Detected hash mismatch error, removing bad file %s", hash)
+ cr.storageManager.RemoveForAll(hash)
+ }
+ return KeepAliveFailed
+ }
+ }
+ log.TrErrorf("error.cluster.keepalive.failed", ero)
+ return KeepAliveFailed
+ }
+ log.TrInfof("info.cluster.keepalive.success", hits, utils.BytesToUnit((float64)(hbts)), data[1])
+ cr.hits.Add(-hits)
+ cr.hbts.Add(-hbts)
+ if data[1] == false {
+ cr.markKicked()
+ return KeepAliveKicked
+ }
+ return KeepAliveSucceed
+}
diff --git a/token.go b/cluster/requests.go
similarity index 64%
rename from token.go
rename to cluster/requests.go
index a86f1b91..0899c10e 100644
--- a/token.go
+++ b/cluster/requests.go
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package main
+package cluster
import (
"bytes"
@@ -26,6 +26,8 @@ import (
"crypto/hmac"
"encoding/hex"
"encoding/json"
+ "errors"
+ "fmt"
"net/http"
"net/url"
"time"
@@ -85,7 +87,7 @@ func (cr *Cluster) fetchToken(ctx context.Context) (token *ClusterToken, err err
}
}()
req, err := cr.makeReq(ctx, http.MethodGet, "/openbmclapi-agent/challenge", url.Values{
- "clusterId": {cr.clusterId},
+ "clusterId": {cr.ID()},
})
if err != nil {
return
@@ -109,7 +111,7 @@ func (cr *Cluster) fetchToken(ctx context.Context) (token *ClusterToken, err err
}
var buf [32]byte
- hs := hmac.New(crypto.SHA256.New, ([]byte)(cr.clusterSecret))
+ hs := hmac.New(crypto.SHA256.New, ([]byte)(cr.Secret()))
hs.Write(([]byte)(res1.Challenge))
signature := hex.EncodeToString(hs.Sum(buf[:0]))
@@ -118,7 +120,7 @@ func (cr *Cluster) fetchToken(ctx context.Context) (token *ClusterToken, err err
Challenge string `json:"challenge"`
Signature string `json:"signature"`
}{
- ClusterId: cr.clusterId,
+ ClusterId: cr.ID(),
Challenge: res1.Challenge,
Signature: signature,
})
@@ -158,7 +160,7 @@ func (cr *Cluster) refreshToken(ctx context.Context, oldToken string) (token *Cl
ClusterId string `json:"clusterId"`
Token string `json:"token"`
}{
- ClusterId: cr.clusterId,
+ ClusterId: cr.ID(),
Token: oldToken,
})
if err != nil {
@@ -193,3 +195,105 @@ func (cr *Cluster) refreshToken(ctx context.Context, oldToken string) (token *Cl
ExpireAt: time.Now().Add((time.Duration)(res.TTL)*time.Millisecond - 10*time.Second),
}, nil
}
+
+type OpenbmclapiAgentConfig struct {
+ Sync OpenbmclapiAgentSyncConfig `json:"sync"`
+}
+
+type OpenbmclapiAgentSyncConfig struct {
+ Source string `json:"source"`
+ Concurrency int `json:"concurrency"`
+}
+
+func (cr *Cluster) GetConfig(ctx context.Context) (cfg *OpenbmclapiAgentConfig, err error) {
+ req, err := cr.makeReqWithAuth(ctx, http.MethodGet, "/openbmclapi/configuration", nil)
+ if err != nil {
+ return
+ }
+ res, err := cr.client.DoUseCache(req)
+ if err != nil {
+ return
+ }
+ defer res.Body.Close()
+ if res.StatusCode != http.StatusOK {
+ err = utils.NewHTTPStatusErrorFromResponse(res)
+ return
+ }
+ cfg = new(OpenbmclapiAgentConfig)
+ if err = json.NewDecoder(res.Body).Decode(cfg); err != nil {
+ cfg = nil
+ return
+ }
+ return
+}
+
+type CertKeyPair struct {
+ Cert string `json:"cert"`
+ Key string `json:"key"`
+}
+
+func (cr *Cluster) RequestCert(ctx context.Context) (ckp *CertKeyPair, err error) {
+ resCh, err := cr.socket.EmitWithAck("request-cert")
+ if err != nil {
+ return
+ }
+ var data []any
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case data = <-resCh:
+ }
+ if ero := data[0]; ero != nil {
+ err = fmt.Errorf("socket.io remote error: %v", ero)
+ return
+ }
+ pair := data[1].(map[string]any)
+ ckp = new(CertKeyPair)
+ var ok bool
+ if ckp.Cert, ok = pair["cert"].(string); !ok {
+ err = fmt.Errorf(`"cert" is not a string, got %T`, pair["cert"])
+ return
+ }
+ if ckp.Key, ok = pair["key"].(string); !ok {
+ err = fmt.Errorf(`"key" is not a string, got %T`, pair["key"])
+ return
+ }
+ return
+}
+
+func (cr *Cluster) ReportDownload(ctx context.Context, response *http.Response, err error) error {
+ if errors.Is(err, context.Canceled) {
+ return nil
+ }
+
+ type ReportPayload struct {
+ Urls []string `json:"urls"`
+ Error utils.EmbedJSON[struct {
+ Message string `json:"message"`
+ }] `json:"error"`
+ }
+ var payload ReportPayload
+ redirects := utils.GetRedirects(response)
+ payload.Urls = make([]string, len(redirects))
+ for i, u := range redirects {
+ payload.Urls[i] = u.String()
+ }
+ payload.Error.V.Message = err.Error()
+ data, err := json.Marshal(payload)
+ if err != nil {
+ return err
+ }
+ req, err := cr.makeReqWithAuthBody(ctx, http.MethodPost, "/openbmclapi/report", nil, bytes.NewReader(data))
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+ resp, err := cr.client.Do(req)
+ if err != nil {
+ return err
+ }
+ if resp.StatusCode/100 != 2 {
+ return utils.NewHTTPStatusErrorFromResponse(resp)
+ }
+ return nil
+}
diff --git a/cluster/socket.go b/cluster/socket.go
new file mode 100644
index 00000000..a84625ab
--- /dev/null
+++ b/cluster/socket.go
@@ -0,0 +1,145 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/LiterMC/socket.io"
+ "github.com/LiterMC/socket.io/engine.io"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+ "github.com/LiterMC/go-openbmclapi/log"
+)
+
+// Connect connects to the central server
+// The context passed in only affect the logical of Connect method
+// Connection will not be closed after disable
+//
+// See Disconnect
+func (cr *Cluster) Connect(ctx context.Context) error {
+ if !cr.Status().Disconnected() {
+ return errors.New("Attempt to connect while connecting")
+ }
+
+ cr.status.Store(api.ClusterConnecting)
+ defer cr.status.CompareAndSwap(api.ClusterConnecting, api.ClusterDisconnected)
+
+ _, err := cr.GetAuthToken(ctx)
+ if err != nil {
+ return fmt.Errorf("Auth failed %w", err)
+ }
+
+ engio, err := engine.NewSocket(engine.Options{
+ Host: cr.opts.Server,
+ Path: "/socket.io/",
+ ExtraHeaders: http.Header{
+ "Origin": {cr.opts.Server},
+ "User-Agent": {build.ClusterUserAgent},
+ },
+ DialTimeout: time.Minute * 6,
+ })
+ if err != nil {
+ return fmt.Errorf("Could not parse Engine.IO options: %w", err)
+ }
+ if ctx.Value("cluster.options.engine-io.debug") == true {
+ engio.OnRecv(func(s *engine.Socket, data []byte) {
+ log.Debugf("Engine.IO %s recv: %q", s.ID(), (string)(data))
+ })
+ engio.OnSend(func(s *engine.Socket, data []byte) {
+ log.Debugf("Engine.IO %s send: %q", s.ID(), (string)(data))
+ })
+ }
+ engio.OnConnect(func(s *engine.Socket) {
+ log.Infof("Engine.IO %s connected for cluster %s", s.ID(), cr.ID())
+ })
+ engio.OnDisconnect(cr.onDisconnected)
+ engio.OnDialError(func(s *engine.Socket, err *engine.DialErrorContext) {
+ if err.Count() < 0 {
+ return
+ }
+ log.TrErrorf("error.cluster.connect.failed", cr.ID(), err.Count(), cr.gcfg.MaxReconnectCount, err.Err())
+ if cr.gcfg.MaxReconnectCount >= 0 && err.Count() >= cr.gcfg.MaxReconnectCount {
+ log.TrErrorf("error.cluster.connect.failed.toomuch", cr.ID())
+ s.Close()
+ }
+ })
+ log.Infof("Dialing %s for cluster %s(%s)", engio.URL().String(), cr.Name(), cr.ID())
+ if err := engio.Dial(ctx); err != nil {
+ return fmt.Errorf("Dial error: %w", err)
+ }
+
+ cr.socket = socket.NewSocket(engio, socket.WithAuthTokenFn(func() (string, error) {
+ token, err := cr.GetAuthToken(ctx)
+ if err != nil {
+ log.TrErrorf("error.cluster.auth.failed", err)
+ return "", err
+ }
+ return token, nil
+ }))
+ cr.socket.OnError(func(_ *socket.Socket, err error) {
+ log.Errorf("Socket.IO error: %v", err)
+ })
+ cr.socket.OnMessage(func(event string, data []any) {
+ if event == "message" {
+ log.Infof("[remote]: %v", data[0])
+ } else if event == "exception" {
+ log.Errorf("[remote exception]: %v", data[0])
+ } else if event == "warden-error" {
+ log.Warnf("[warden]: %v", data[0])
+ }
+ })
+ log.Infof("Cluster %s is connecting to socket.io namespace", cr.Name())
+ if err := cr.socket.Connect(""); err != nil {
+ return fmt.Errorf("Namespace connect error: %w", err)
+ }
+
+ cr.status.Store(api.ClusterDisabled)
+ return nil
+}
+
+// Disconnect close the connection which connected to the central server
+// Disconnect will not disable the cluster
+//
+// See Connect
+func (cr *Cluster) Disconnect(context.Context) error {
+ if cr.Status().Disconnected() {
+ return nil
+ }
+ cr.mux.Lock()
+ defer cr.mux.Unlock()
+ err := cr.socket.Close()
+ cr.status.Store(api.ClusterDisconnected)
+ cr.socket = nil
+ return err
+}
+
+func (cr *Cluster) onDisconnected(s *engine.Socket, err error) {
+ if err != nil {
+ log.Warnf("Engine.IO %s disconnected: %v", s.ID(), err)
+ }
+ cr.status.Store(api.ClusterDisconnected)
+ cr.socket = nil
+}
diff --git a/cluster/stat.go b/cluster/stat.go
new file mode 100644
index 00000000..d96a3307
--- /dev/null
+++ b/cluster/stat.go
@@ -0,0 +1,363 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2023 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "encoding/json"
+ "errors"
+ "os"
+ "path/filepath"
+ "slices"
+ "sort"
+ "strings"
+ "sync"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
+)
+
+const statsOverallFileName = "stat.json"
+
+type StatManager struct {
+ mux sync.RWMutex
+
+ clusters []string
+ storages []string
+
+ Overall *api.AccessStatData
+ Clusters map[string]*api.AccessStatData
+ Storages map[string]*api.AccessStatData
+}
+
+var _ json.Marshaler = (*StatManager)(nil)
+
+func NewStatManager() *StatManager {
+ return &StatManager{
+ Overall: new(api.AccessStatData),
+ Clusters: make(map[string]*api.AccessStatData),
+ Storages: make(map[string]*api.AccessStatData),
+ }
+}
+
+func (m *StatManager) GetStatus() api.StatusData {
+ m.mux.RLock()
+ defer m.mux.RUnlock()
+
+ return api.StatusData{
+ StartAt: build.StartAt,
+ Clusters: m.clusters,
+ Storages: m.storages,
+ }
+}
+
+func (m *StatManager) AddCluster(name string) {
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ i := sort.SearchStrings(m.clusters, name)
+ if i == len(m.clusters) || m.clusters[i] != name {
+ m.clusters = slices.Insert(m.clusters, i, name)
+ }
+}
+
+func (m *StatManager) AddStorage(name string) {
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ i := sort.SearchStrings(m.storages, name)
+ if i == len(m.storages) || m.storages[i] != name {
+ m.storages = slices.Insert(m.storages, i, name)
+ }
+}
+
+func (m *StatManager) RemoveCluster(name string) {
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ i := sort.SearchStrings(m.clusters, name)
+ if i < len(m.clusters) && m.clusters[i] == name {
+ m.clusters = slices.Delete(m.clusters, i, i+1)
+ }
+}
+
+func (m *StatManager) RemoveStorage(name string) {
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ i := sort.SearchStrings(m.storages, name)
+ if i < len(m.storages) && m.storages[i] == name {
+ m.storages = slices.Delete(m.storages, i, i+1)
+ }
+}
+
+func (m *StatManager) RenameCluster(oldName, newName string) {
+ if oldName == newName {
+ return
+ }
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ oldInd := sort.SearchStrings(m.clusters, oldName)
+ if oldInd == len(m.clusters) || m.clusters[oldInd] != oldName {
+ return
+ }
+ newInd := sort.SearchStrings(m.clusters, newName)
+ if oldInd == newInd || oldInd+1 == newInd {
+ m.clusters[oldInd] = newName
+ } else if oldInd < newInd {
+ copy(m.clusters[oldInd:], m.clusters[oldInd+1:newInd])
+ m.clusters[newInd-1] = newName
+ } else /*if oldInd > newInd*/ {
+ copy(m.clusters[newInd+1:], m.clusters[newInd:oldInd])
+ m.clusters[newInd] = newName
+ }
+ m.Clusters[newName] = m.Clusters[oldName]
+ delete(m.Clusters, oldName)
+}
+
+func (m *StatManager) RenameStorage(oldName, newName string) {
+ if oldName == newName {
+ return
+ }
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ oldInd := sort.SearchStrings(m.storages, oldName)
+ if oldInd == len(m.storages) || m.storages[oldInd] != oldName {
+ return
+ }
+ newInd := sort.SearchStrings(m.storages, newName)
+ if oldInd == newInd || oldInd+1 == newInd {
+ m.storages[oldInd] = newName
+ } else if oldInd < newInd {
+ copy(m.storages[oldInd:], m.storages[oldInd+1:newInd])
+ m.storages[newInd-1] = newName
+ } else /*if oldInd > newInd*/ {
+ copy(m.storages[newInd+1:], m.storages[newInd:oldInd])
+ m.storages[newInd] = newName
+ }
+ m.Storages[newName] = m.Storages[oldName]
+ delete(m.Storages, oldName)
+}
+
+var emptyStat = api.NewAccessStatData()
+
+func (m *StatManager) GetClusterAccessStat(name string) *api.AccessStatData {
+ d := m.Clusters[name]
+ if d == nil {
+ return emptyStat
+ }
+ return d
+}
+
+func (m *StatManager) GetStorageAccessStat(name string) *api.AccessStatData {
+ d := m.Storages[name]
+ if d == nil {
+ return emptyStat
+ }
+ return d
+}
+
+func (m *StatManager) AddHit(bytes int64, cluster, storage string, userAgent string) {
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ data := &api.StatInstData{
+ Hits: 1,
+ Bytes: bytes,
+ }
+ m.Overall.Update(data)
+ if userAgent != "" {
+ m.Overall.Accesses[userAgent]++
+ }
+ if cluster != "" {
+ d := m.Clusters[cluster]
+ if d == nil {
+ d = api.NewAccessStatData()
+ m.Clusters[cluster] = d
+ }
+ d.Update(data)
+ if userAgent != "" {
+ d.Accesses[userAgent]++
+ }
+ }
+ if storage != "" {
+ d := m.Storages[storage]
+ if d == nil {
+ d = api.NewAccessStatData()
+ m.Storages[storage] = d
+ }
+ d.Update(data)
+ if userAgent != "" {
+ d.Accesses[userAgent]++
+ }
+ }
+}
+
+func (m *StatManager) Load(dir string) error {
+ clustersDir, storagesDir := filepath.Join(dir, "clusters"), filepath.Join(dir, "storages")
+
+ m.mux.Lock()
+ defer m.mux.Unlock()
+
+ *m.Overall = api.AccessStatData{}
+ clear(m.Clusters)
+ clear(m.Storages)
+
+ if err := loadStatData(m.Overall, filepath.Join(dir, statsOverallFileName)); err != nil {
+ return err
+ }
+ if entries, err := os.ReadDir(clustersDir); err == nil {
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
+ }
+ if name, ok := strings.CutSuffix(entry.Name(), ".json"); ok {
+ d := new(api.AccessStatData)
+ if err := loadStatData(d, filepath.Join(clustersDir, entry.Name())); err != nil {
+ return err
+ }
+ m.Clusters[name] = d
+ }
+ }
+ }
+ if entries, err := os.ReadDir(storagesDir); err == nil {
+ for _, entry := range entries {
+ if entry.IsDir() {
+ continue
+ }
+ if name, ok := strings.CutSuffix(entry.Name(), ".json"); ok {
+ d := new(api.AccessStatData)
+ if err := loadStatData(d, filepath.Join(storagesDir, entry.Name())); err != nil {
+ return err
+ }
+ m.Storages[name] = d
+ }
+ }
+ }
+ return nil
+}
+
+func (m *StatManager) Save(dir string) error {
+ clustersDir, storagesDir := filepath.Join(dir, "clusters"), filepath.Join(dir, "storages")
+
+ m.mux.RLock()
+ defer m.mux.RUnlock()
+
+ if err := saveStatData(m.Overall, filepath.Join(dir, statsOverallFileName)); err != nil {
+ return err
+ }
+ if err := os.Mkdir(clustersDir, 0755); err != nil && !errors.Is(err, os.ErrExist) {
+ return err
+ }
+ if err := os.Mkdir(storagesDir, 0755); err != nil && !errors.Is(err, os.ErrExist) {
+ return err
+ }
+ for name, data := range m.Clusters {
+ if err := saveStatData(data, filepath.Join(clustersDir, name+".json")); err != nil {
+ return err
+ }
+ }
+ for name, data := range m.Storages {
+ if err := saveStatData(data, filepath.Join(storagesDir, name+".json")); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (m *StatManager) MarshalJSON() ([]byte, error) {
+ m.mux.RLock()
+ defer m.mux.RUnlock()
+
+ return json.Marshal(map[string]any{
+ "overall": m.Overall,
+ "clusters": m.Clusters,
+ "storages": m.Storages,
+ })
+}
+
+func loadStatData(s *api.AccessStatData, name string) error {
+ if err := parseFileOrOld(name, func(buf []byte) error {
+ return json.Unmarshal(buf, s)
+ }); err != nil {
+ return err
+ }
+
+ if s.Years == nil {
+ s.Years = make(map[string]api.StatInstData, 2)
+ }
+ if s.Accesses == nil {
+ s.Accesses = make(map[string]int, 5)
+ }
+ return nil
+}
+
+func saveStatData(s *api.AccessStatData, name string) error {
+ buf, err := json.Marshal(s)
+ if err != nil {
+ return err
+ }
+ if err := writeFileWithOld(name, buf, 0644); err != nil {
+ return err
+ }
+ return nil
+}
+
+func parseFileOrOld(path string, parser func(buf []byte) error) error {
+ oldpath := path + ".old"
+ buf, err := os.ReadFile(path)
+ if err == nil {
+ if err = parser(buf); err == nil {
+ return err
+ }
+ }
+ buf, er := os.ReadFile(oldpath)
+ if er == nil {
+ if er = parser(buf); er == nil {
+ os.WriteFile(path, buf, 0644)
+ return nil
+ }
+ }
+ if errors.Is(err, os.ErrNotExist) {
+ if errors.Is(er, os.ErrNotExist) {
+ return nil
+ }
+ err = er
+ }
+ return err
+}
+
+func writeFileWithOld(path string, buf []byte, mode os.FileMode) error {
+ oldpath := path + ".old"
+ if err := os.Remove(oldpath); err != nil && !errors.Is(err, os.ErrNotExist) {
+ return err
+ }
+ if err := os.Rename(path, oldpath); err != nil && !errors.Is(err, os.ErrNotExist) {
+ return err
+ }
+ if err := os.WriteFile(path, buf, mode); err != nil {
+ return err
+ }
+ if err := os.WriteFile(oldpath, buf, mode); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/cluster/status.go b/cluster/status.go
new file mode 100644
index 00000000..bdbf6009
--- /dev/null
+++ b/cluster/status.go
@@ -0,0 +1,53 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "github.com/LiterMC/go-openbmclapi/api"
+)
+
+func (cr *Cluster) Status() api.ClusterStatus {
+ return (api.ClusterStatus)(cr.status.Load())
+}
+
+// Disabled returns true if the cluster is disabled manually
+func (cr *Cluster) Disabled() bool {
+ return cr.Status() == api.ClusterDisabled && !cr.shouldEnable.Load()
+}
+
+// IsKicked returns true if the cluster is kicked by the central server
+func (cr *Cluster) IsKicked() bool {
+ return cr.Status() == api.ClusterDisabled && cr.shouldEnable.Load()
+}
+
+// WaitForEnable returns a channel which receives true when cluster enabled succeed, or receives false when it failed to enable
+// If the cluster is already enable, the channel always returns true
+// The channel should not be used multiple times
+func (cr *Cluster) WaitForEnable() <-chan bool {
+ cr.mux.Lock()
+ defer cr.mux.Unlock()
+ ch := make(chan bool, 1)
+ if cr.Status().Running() {
+ ch <- true
+ } else {
+ cr.enableSignals = append(cr.enableSignals, ch)
+ }
+ return ch
+}
diff --git a/cluster/storage.go b/cluster/storage.go
new file mode 100644
index 00000000..f4a3a6cb
--- /dev/null
+++ b/cluster/storage.go
@@ -0,0 +1,772 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster
+
+import (
+ "compress/gzip"
+ "compress/zlib"
+ "context"
+ "crypto"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "os"
+ "runtime"
+ "slices"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/hamba/avro/v2"
+ "github.com/klauspost/compress/zstd"
+ "github.com/vbauerster/mpb/v8"
+ "github.com/vbauerster/mpb/v8/decor"
+
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/lang"
+ "github.com/LiterMC/go-openbmclapi/limited"
+ "github.com/LiterMC/go-openbmclapi/log"
+ "github.com/LiterMC/go-openbmclapi/storage"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+// from
+var fileListSchema = avro.MustParse(`{
+ "type": "array",
+ "items": {
+ "type": "record",
+ "name": "fileinfo",
+ "fields": [
+ {"name": "path", "type": "string"},
+ {"name": "hash", "type": "string"},
+ {"name": "size", "type": "long"},
+ {"name": "mtime", "type": "long"}
+ ]
+ }
+}`)
+
+type FileInfo struct {
+ Path string `json:"path" avro:"path"`
+ Hash string `json:"hash" avro:"hash"`
+ Size int64 `json:"size" avro:"size"`
+ Mtime int64 `json:"mtime" avro:"mtime"`
+}
+
+func (cr *Cluster) GetFileList(ctx context.Context, fileMap map[string]*api.StorageFileInfo, forceAll bool) error {
+ var query url.Values
+ lastMod := cr.fileListLastMod
+ if forceAll {
+ lastMod = 0
+ }
+ if lastMod > 0 {
+ query = url.Values{
+ "lastModified": {strconv.FormatInt(lastMod, 10)},
+ }
+ }
+ req, err := cr.makeReqWithAuth(ctx, http.MethodGet, "/openbmclapi/files", query)
+ if err != nil {
+ return err
+ }
+ res, err := cr.client.DoUseCache(req)
+ if err != nil {
+ return err
+ }
+ defer res.Body.Close()
+ switch res.StatusCode {
+ case http.StatusOK:
+ case http.StatusNoContent, http.StatusNotModified:
+ return nil
+ default:
+ return utils.NewHTTPStatusErrorFromResponse(res)
+ }
+ log.Debug("Parsing filelist body ...")
+ zr, err := zstd.NewReader(res.Body)
+ if err != nil {
+ return err
+ }
+ defer zr.Close()
+ var files []FileInfo
+ if err := avro.NewDecoderForSchema(fileListSchema, zr).Decode(&files); err != nil {
+ return err
+ }
+
+ for _, f := range files {
+ if f.Mtime > lastMod {
+ lastMod = f.Mtime
+ }
+ if ff, ok := fileMap[f.Hash]; ok {
+ if ff.Size != f.Size {
+ log.Panicf("Hash conflict detected, hash of both %q (%dB) and %v (%dB) is %s", f.Path, f.Size, ff.URLs, ff.Size, f.Hash)
+ }
+ for _, s := range cr.storages {
+ sto := cr.storageManager.Storages[s]
+ if i, ok := slices.BinarySearchFunc(ff.Storages, sto, storageIdSortFunc); !ok {
+ ff.Storages = slices.Insert(ff.Storages, i, sto)
+ }
+ }
+ } else {
+ ff := &api.StorageFileInfo{
+ Hash: f.Hash,
+ Size: f.Size,
+ Storages: make([]storage.Storage, len(cr.storages)),
+ URLs: make(map[string]api.RequestPath),
+ }
+ for i, s := range cr.storages {
+ ff.Storages[i] = cr.storageManager.Storages[s]
+ }
+ slices.SortFunc(ff.Storages, storageIdSortFunc)
+ req, err := cr.makeReqWithAuth(context.Background(), http.MethodGet, f.Path, nil)
+ if err != nil {
+ return err
+ }
+ ff.URLs[req.URL.String()] = api.RequestPath{
+ Request: req,
+ Cluster: cr,
+ Path: f.Path,
+ }
+ fileMap[f.Hash] = ff
+ }
+ }
+ cr.fileListLastMod = lastMod
+ log.Debugf("Filelist parsed, length = %d, lastMod = %d", len(files), lastMod)
+ return nil
+}
+
+func storageIdSortFunc(a, b storage.Storage) int {
+ if a.Id() < b.Id() {
+ return -1
+ }
+ return 1
+}
+
+var emptyStr string
+
+func checkFile(
+ ctx context.Context,
+ manager *storage.Manager,
+ files map[string]*api.StorageFileInfo,
+ heavy bool,
+ missing map[string]*api.StorageFileInfo,
+ pg *mpb.Progress,
+) (err error) {
+ var missingCount atomic.Int32
+ addMissing := func(f *api.StorageFileInfo, sto storage.Storage) {
+ missingCount.Add(1)
+ if info, ok := missing[f.Hash]; ok {
+ info.Storages = append(info.Storages, sto)
+ } else {
+ info := new(api.StorageFileInfo)
+ *info = *f
+ info.Storages = []storage.Storage{sto}
+ missing[f.Hash] = info
+ }
+ }
+
+ log.TrInfof("info.check.start", heavy)
+
+ var (
+ checkingHash atomic.Pointer[string]
+ lastCheckingHash string
+ slots *limited.BufSlots
+ wg sync.WaitGroup
+ )
+ checkingHash.Store(&emptyStr)
+
+ if heavy {
+ slots = limited.NewBufSlots(runtime.GOMAXPROCS(0) * 2)
+ }
+
+ bar := pg.AddBar(0,
+ mpb.BarRemoveOnComplete(),
+ mpb.PrependDecorators(
+ decor.Name(lang.Tr("hint.check.checking")),
+ decor.OnCondition(
+ decor.Any(func(decor.Statistics) string {
+ c, l := slots.Cap(), slots.Len()
+ return fmt.Sprintf(" (%d / %d)", c-l, c)
+ }),
+ heavy,
+ ),
+ ),
+ mpb.AppendDecorators(
+ decor.CountersNoUnit("%d / %d", decor.WCSyncSpaceR),
+ decor.NewPercentage("%d", decor.WCSyncSpaceR),
+ decor.EwmaETA(decor.ET_STYLE_GO, 60),
+ ),
+ mpb.BarExtender((mpb.BarFillerFunc)(func(w io.Writer, _ decor.Statistics) (err error) {
+ lastCheckingHash = *checkingHash.Load()
+ if lastCheckingHash != "" {
+ _, err = fmt.Fprintln(w, "\t", lastCheckingHash)
+ }
+ return
+ }), false),
+ )
+ defer bar.Wait()
+ defer bar.Abort(true)
+
+ bar.SetTotal(0x100, false)
+
+ ssizeMap := make(map[storage.Storage]map[string]int64, len(manager.Storages))
+ for _, sto := range manager.Storages {
+ sizeMap := make(map[string]int64, len(files))
+ ssizeMap[sto] = sizeMap
+ wg.Add(1)
+ go func(sto storage.Storage, sizeMap map[string]int64) {
+ defer wg.Done()
+ start := time.Now()
+ var checkedMp [256]bool
+ if err := sto.WalkDir(func(hash string, size int64) error {
+ if n := utils.HexTo256(hash); !checkedMp[n] {
+ checkedMp[n] = true
+ now := time.Now()
+ bar.EwmaIncrement(now.Sub(start))
+ start = now
+ }
+ sizeMap[hash] = size
+ return nil
+ }); err != nil {
+ log.Errorf("Cannot walk %s: %v", sto.Id(), err)
+ return
+ }
+ }(sto, sizeMap)
+ }
+ wg.Wait()
+
+ bar.SetCurrent(0)
+ bar.SetTotal((int64)(len(files)), false)
+ for _, f := range files {
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+ start := time.Now()
+ hash := f.Hash
+ checkingHash.Store(&hash)
+ if f.Size == 0 {
+ log.Debugf("Skipped empty file %s", hash)
+ bar.EwmaIncrement(time.Since(start))
+ continue
+ }
+ for _, sto := range f.Storages {
+ name := sto.Id() + "/" + hash
+ size, ok := ssizeMap[sto][hash]
+ if !ok {
+ // log.Debugf("Could not found file %q", name)
+ addMissing(f, sto)
+ bar.EwmaIncrement(time.Since(start))
+ continue
+ }
+ if size != f.Size {
+ log.TrWarnf("warn.check.modified.size", name, size, f.Size)
+ addMissing(f, sto)
+ bar.EwmaIncrement(time.Since(start))
+ continue
+ }
+ if !heavy {
+ bar.EwmaIncrement(time.Since(start))
+ continue
+ }
+ hashMethod, err := getHashMethod(len(hash))
+ if err != nil {
+ log.TrErrorf("error.check.unknown.hash.method", hash)
+ bar.EwmaIncrement(time.Since(start))
+ continue
+ }
+ _, buf, free := slots.Alloc(ctx)
+ if buf == nil {
+ return ctx.Err()
+ }
+ wg.Add(1)
+ go func(f *api.StorageFileInfo, buf []byte, free func()) {
+ defer log.RecoverPanic(nil)
+ defer wg.Done()
+ miss := true
+ r, err := sto.Open(hash)
+ if err != nil {
+ log.TrErrorf("error.check.open.failed", name, err)
+ } else {
+ hw := hashMethod.New()
+ _, err = io.CopyBuffer(hw, r, buf[:])
+ r.Close()
+ if err != nil {
+ log.TrErrorf("error.check.hash.failed", name, err)
+ } else if hs := hex.EncodeToString(hw.Sum(buf[:0])); hs != hash {
+ log.TrWarnf("warn.check.modified.hash", name, hs, hash)
+ } else {
+ miss = false
+ }
+ }
+ bar.EwmaIncrement(time.Since(start))
+ free()
+ if miss {
+ addMissing(f, sto)
+ }
+ }(f, buf, free)
+ }
+ }
+ wg.Wait()
+
+ checkingHash.Store(&emptyStr)
+
+ bar.SetTotal(-1, true)
+ log.TrInfof("info.check.done", missingCount.Load())
+ return nil
+}
+
+type syncStats struct {
+ slots *limited.BufSlots
+
+ totalSize int64
+ okCount, failCount atomic.Int32
+ totalFiles int
+
+ pg *mpb.Progress
+ totalBar *mpb.Bar
+ lastInc atomic.Int64
+}
+
+func (c *HTTPClient) SyncFiles(
+ ctx context.Context,
+ manager *storage.Manager,
+ files map[string]*api.StorageFileInfo,
+ heavy bool,
+ slots int,
+) error {
+ pg := mpb.New(mpb.WithRefreshRate(time.Second/2), mpb.WithAutoRefresh(), mpb.WithWidth(140))
+ defer pg.Shutdown()
+ log.SetLogOutput(pg)
+ defer log.SetLogOutput(nil)
+
+ missingMap := make(map[string]*api.StorageFileInfo)
+ if err := checkFile(ctx, manager, files, heavy, missingMap, pg); err != nil {
+ return err
+ }
+
+ totalFiles := len(missingMap)
+
+ var stats syncStats
+ stats.pg = pg
+ stats.slots = limited.NewBufSlots(slots)
+ stats.totalFiles = totalFiles
+ for _, f := range missingMap {
+ stats.totalSize += f.Size
+ }
+
+ var barUnit decor.SizeB1024
+ stats.lastInc.Store(time.Now().UnixNano())
+ stats.totalBar = pg.AddBar(stats.totalSize,
+ mpb.BarRemoveOnComplete(),
+ mpb.BarPriority(stats.slots.Cap()),
+ mpb.PrependDecorators(
+ decor.Name(lang.Tr("hint.sync.total")),
+ decor.NewPercentage("%.2f"),
+ ),
+ mpb.AppendDecorators(
+ decor.Any(func(decor.Statistics) string {
+ return fmt.Sprintf("(%d + %d / %d) ", stats.okCount.Load(), stats.failCount.Load(), stats.totalFiles)
+ }),
+ decor.Counters(barUnit, "(%.1f/%.1f) "),
+ decor.EwmaSpeed(barUnit, "%.1f ", 30),
+ decor.OnComplete(
+ decor.EwmaETA(decor.ET_STYLE_GO, 30), "done",
+ ),
+ ),
+ )
+
+ log.TrInfof("hint.sync.start", totalFiles, utils.BytesToUnit((float64)(stats.totalSize)))
+ start := time.Now()
+
+ done := make(chan []storage.Storage, 1)
+ ctx, cancel := context.WithCancelCause(ctx)
+ defer cancel(nil)
+
+ stLen := len(manager.Storages)
+ aliveStorages := make(map[storage.Storage]struct{}, stLen)
+ for _, s := range manager.Storages {
+ if !s.Inited() {
+ log.Errorf("Storage %s is not initialized", s.String())
+ continue
+ }
+ tctx, cancel := context.WithTimeout(ctx, time.Second*10)
+ err := s.CheckUpload(tctx)
+ cancel()
+ if err != nil {
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+ log.Errorf("Storage %s does not work: %v", s.String(), err)
+ } else {
+ aliveStorages[s] = struct{}{}
+ }
+ }
+ if len(aliveStorages) == 0 {
+ err := errors.New("All storages are broken")
+ log.TrErrorf("error.sync.failed", err)
+ return err
+ }
+ if len(aliveStorages) < stLen {
+ log.TrErrorf("error.sync.part.working", len(aliveStorages), stLen)
+ select {
+ case <-time.After(time.Minute):
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ }
+
+ go func() {
+ for _, info := range missingMap {
+ log.Debugf("File %s is for %s", info.Hash, joinStorageIDs(info.Storages))
+ fileRes, err := c.fetchFile(ctx, &stats, info)
+ if err != nil {
+ if err != ctx.Err() {
+ cancel(err)
+ }
+ return
+ }
+ go func(info *api.StorageFileInfo, fileRes <-chan *os.File) {
+ defer log.RecordPanic()
+ select {
+ case srcFd := <-fileRes:
+ // cr.syncProg.Add(1)
+ if srcFd == nil {
+ select {
+ case done <- nil: // TODO: or all storage?
+ case <-ctx.Done():
+ }
+ return
+ }
+ defer os.Remove(srcFd.Name())
+ defer srcFd.Close()
+ // acquire slot here
+ slotId, buf, free := stats.slots.Alloc(ctx)
+ if buf == nil {
+ return
+ }
+ defer free()
+ _ = slotId
+ var failed []storage.Storage
+ for _, target := range info.Storages {
+ if _, err = srcFd.Seek(0, io.SeekStart); err != nil {
+ log.Errorf("Cannot seek file %q to start: %v", srcFd.Name(), err)
+ continue
+ }
+ if err = target.Create(info.Hash, srcFd); err != nil {
+ failed = append(failed, target)
+ log.TrErrorf("error.sync.create.failed", target.String(), info.Hash, err)
+ continue
+ }
+ }
+ free()
+ srcFd.Close()
+ os.Remove(srcFd.Name())
+ select {
+ case done <- failed:
+ case <-ctx.Done():
+ }
+ case <-ctx.Done():
+ return
+ }
+ }(info, fileRes)
+ }
+ }()
+
+ for range len(missingMap) {
+ select {
+ case failed := <-done:
+ for _, s := range failed {
+ if _, ok := aliveStorages[s]; ok {
+ delete(aliveStorages, s)
+ log.Debugf("Broken storage %d / %d", stLen-len(aliveStorages), stLen)
+ if len(aliveStorages) == 0 {
+ cancel(nil)
+ err := errors.New("All storages are broken")
+ log.TrErrorf("error.sync.failed", err)
+ return err
+ }
+ }
+ }
+ case <-ctx.Done():
+ log.TrWarnf("warn.sync.interrupted")
+ return ctx.Err()
+ }
+ }
+
+ use := time.Since(start)
+ stats.totalBar.Abort(true)
+ pg.Wait()
+
+ log.TrInfof("hint.sync.done", use, utils.BytesToUnit((float64)(stats.totalSize)/use.Seconds()))
+ return nil
+}
+
+func (c *HTTPClient) fetchFile(ctx context.Context, stats *syncStats, f *api.StorageFileInfo) (<-chan *os.File, error) {
+ const maxRetryCount = 10
+
+ hashMethod, err := getHashMethod(len(f.Hash))
+ if err != nil {
+ return nil, err
+ }
+
+ slotId, buf, free := stats.slots.Alloc(ctx)
+ if buf == nil {
+ return nil, ctx.Err()
+ }
+
+ reqInd := 0
+ reqs := make([]api.RequestPath, 0, len(f.URLs))
+ for _, rq := range f.URLs {
+ reqs = append(reqs, rq)
+ }
+
+ fileRes := make(chan *os.File, 1)
+ go func() {
+ defer log.RecordPanic()
+ defer free()
+ defer close(fileRes)
+
+ var barUnit decor.SizeB1024
+ var tried atomic.Int32
+ tried.Store(1)
+
+ bar := stats.pg.AddBar(f.Size,
+ mpb.BarRemoveOnComplete(),
+ mpb.BarPriority(slotId),
+ mpb.PrependDecorators(
+ decor.Name(lang.Tr("hint.sync.downloading")),
+ decor.Any(func(decor.Statistics) string {
+ tc := tried.Load()
+ if tc <= 1 {
+ return ""
+ }
+ return fmt.Sprintf("(%d/%d) ", tc, maxRetryCount)
+ }),
+ decor.Name(f.Hash, decor.WCSyncSpaceR),
+ ),
+ mpb.AppendDecorators(
+ decor.NewPercentage("%d", decor.WCSyncSpace),
+ decor.Counters(barUnit, "[%.1f / %.1f]", decor.WCSyncSpace),
+ decor.EwmaSpeed(barUnit, "%.1f", 30, decor.WCSyncSpace),
+ decor.OnComplete(
+ decor.EwmaETA(decor.ET_STYLE_GO, 30, decor.WCSyncSpace), "done",
+ ),
+ ),
+ )
+ defer bar.Abort(true)
+
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ log.Errorf("Cannot create temporary file: %s", err)
+ stats.failCount.Add(1)
+ return
+ }
+ successed := false
+ defer func(fd *os.File) {
+ if !successed {
+ fd.Close()
+ os.Remove(fd.Name())
+ }
+ }(fd)
+ // prealloc space
+ if err := fd.Truncate(f.Size); err != nil {
+ log.Warnf("File space pre-alloc failed: %v", err)
+ }
+
+ downloadOnce := func() error {
+ if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ return err
+ }
+ rp := reqs[reqInd]
+ if err := c.fetchFileWithBuf(ctx, rp.Request, f.Size, hashMethod, f.Hash, fd, buf, func(r io.Reader) io.Reader {
+ return utils.ProxyPBReader(r, bar, stats.totalBar, &stats.lastInc)
+ }); err != nil {
+ reqInd = (reqInd + 1) % len(reqs)
+ var rerr *utils.RedirectError
+ if ctx.Err() == nil && errors.As(err, &rerr) {
+ go func(ctx context.Context) {
+ if err := rp.Cluster.ReportDownload(ctx, rerr.GetResponse(), rerr.Unwrap()); err != nil {
+ log.Warnf("Report API error: %v", err)
+ }
+ }(context.WithoutCancel(ctx))
+ }
+ return err
+ }
+ return nil
+ }
+
+ interval := time.Second
+ for {
+ bar.SetCurrent(0)
+ err := downloadOnce()
+ if err == nil {
+ break
+ }
+ bar.SetRefill(bar.Current())
+
+ c := tried.Add(1)
+ if c > maxRetryCount || errors.Is(err, context.Canceled) {
+ log.TrErrorf("error.sync.download.failed", f.Hash, err)
+ stats.failCount.Add(1)
+ return
+ }
+ log.TrErrorf("error.sync.download.failed.retry", f.Hash, interval, err)
+ select {
+ case <-time.After(interval):
+ interval = min(interval*2, time.Minute*10)
+ case <-ctx.Done():
+ stats.failCount.Add(1)
+ return
+ }
+ }
+ successed = true
+ fileRes <- fd
+ stats.okCount.Add(1)
+ log.Infof(lang.Tr("info.sync.downloaded"), f.Hash,
+ utils.BytesToUnit((float64)(f.Size)),
+ (float64)(stats.totalBar.Current())/(float64)(stats.totalSize)*100)
+ }()
+ return fileRes, nil
+}
+
+type fileSizeMismatchError struct {
+ Has int64
+ Want int64
+}
+
+func (e *fileSizeMismatchError) Error() string {
+ return fmt.Sprintf("File size wrong, got %d, expect %d", e.Has, e.Want)
+}
+
+type fileHashMismatchError struct {
+ Has string
+ Want string
+}
+
+func (e *fileHashMismatchError) Error() string {
+ return fmt.Sprintf("File hash not match, got %s, expect %s", e.Has, e.Want)
+}
+
+func (c *HTTPClient) fetchFileWithBuf(
+ ctx context.Context, req *http.Request,
+ size int64, hashMethod crypto.Hash, hash string,
+ rw io.ReadWriteSeeker, buf []byte,
+ wrapper func(io.Reader) io.Reader,
+) (err error) {
+ var (
+ res *http.Response
+ r io.Reader
+ )
+ req = req.Clone(ctx)
+ req.Header.Set("Accept-Encoding", "gzip, deflate")
+ if res, err = c.Do(req); err != nil {
+ return
+ }
+ defer res.Body.Close()
+ if res.StatusCode != http.StatusOK {
+ err = utils.NewHTTPStatusErrorFromResponse(res)
+ } else {
+ switch ce := strings.ToLower(res.Header.Get("Content-Encoding")); ce {
+ case "":
+ r = res.Body
+ if res.ContentLength >= 0 && res.ContentLength != size {
+ err = &fileSizeMismatchError{Has: res.ContentLength, Want: size}
+ }
+ case "gzip":
+ r, err = gzip.NewReader(res.Body)
+ case "deflate":
+ r, err = zlib.NewReader(res.Body)
+ default:
+ err = fmt.Errorf("Unexpected Content-Encoding %q", ce)
+ }
+ }
+ if err != nil {
+ return utils.ErrorFromRedirect(err, res)
+ }
+ if wrapper != nil {
+ r = wrapper(r)
+ }
+
+ if n, err := io.CopyBuffer(rw, r, buf); err != nil {
+ return utils.ErrorFromRedirect(err, res)
+ } else if n != size {
+ return utils.ErrorFromRedirect(&fileSizeMismatchError{Has: n, Want: size}, res)
+ }
+ if _, err := rw.Seek(io.SeekStart, 0); err != nil {
+ return err
+ }
+ hw := hashMethod.New()
+ if _, err := io.CopyBuffer(hw, rw, buf); err != nil {
+ return err
+ }
+ if hs := hex.EncodeToString(hw.Sum(buf[:0])); hs != hash {
+ return utils.ErrorFromRedirect(&fileHashMismatchError{Has: hs, Want: hash}, res)
+ }
+ return
+}
+
+func (c *HTTPClient) Gc(
+ ctx context.Context,
+ manager *storage.Manager,
+ files map[string]*api.StorageFileInfo,
+) error {
+ errs := make([]error, len(manager.Storages))
+ var wg sync.WaitGroup
+ for i, s := range manager.Storages {
+ wg.Add(1)
+ go func(i int, s storage.Storage) {
+ defer wg.Done()
+ errs[i] = s.WalkDir(func(hash string, size int64) error {
+ info, ok := files[hash]
+ ok = ok && slices.Contains(info.Storages, s)
+ if !ok {
+ log.Debugf("removing expired file: %s", hash)
+ if err := s.Remove(hash); err != nil {
+ log.Warnf("Cannot remove file %s/%s: %v", s, hash, err)
+ }
+ }
+ return nil
+ })
+ }(i, s)
+ }
+ wg.Wait()
+ return errors.Join(errs...)
+}
+
+func getHashMethod(l int) (hashMethod crypto.Hash, err error) {
+ switch l {
+ case 32:
+ return crypto.MD5, nil
+ case 40:
+ return crypto.SHA1, nil
+ default:
+ return 0, fmt.Errorf("Unexpected hash length %d", l)
+ }
+}
+
+func joinStorageIDs(storages []storage.Storage) string {
+ ss := make([]string, len(storages))
+ for i, s := range storages {
+ ss[i] = s.Id()
+ }
+ return "[" + strings.Join(ss, ", ") + "]"
+}
diff --git a/cluster/storage_test.go b/cluster/storage_test.go
new file mode 100644
index 00000000..0f805744
--- /dev/null
+++ b/cluster/storage_test.go
@@ -0,0 +1,136 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster_test
+
+import (
+ "testing"
+
+ "bytes"
+ "crypto"
+ "io"
+ "net"
+ "net/http"
+ "os"
+ "strconv"
+)
+
+var emptyBytes = make([]byte, 1024)
+
+func startServer() string {
+ listener, err := net.ListenTCP("tcp4", &net.TCPAddr{
+ IP: net.IPv4(127, 0, 0, 1),
+ })
+ if err != nil {
+ panic(err)
+ }
+ server := &http.Server{
+ Handler: (http.HandlerFunc)(func(rw http.ResponseWriter, req *http.Request) {
+ size := 128
+ rw.Header().Set("Content-Length", strconv.Itoa(size*len(emptyBytes)))
+ rw.WriteHeader(http.StatusOK)
+ for range size {
+ rw.Write(emptyBytes)
+ }
+ }),
+ }
+ go server.Serve(listener)
+ return "http://" + listener.Addr().String()
+}
+
+var expectedDownloadHash = []byte{0xfa, 0x43, 0x23, 0x9b, 0xce, 0xe7, 0xb9, 0x7c, 0xa6, 0x2f, 0x0, 0x7c, 0xc6, 0x84, 0x87, 0x56, 0xa, 0x39, 0xe1, 0x9f, 0x74, 0xf3, 0xdd, 0xe7, 0x48, 0x6d, 0xb3, 0xf9, 0x8d, 0xf8, 0xe4, 0x71}
+
+func BenchmarkDownlaodWhileVerify(b *testing.B) {
+ url := startServer()
+ fd, err := os.CreateTemp("", "gotest-")
+ if err != nil {
+ b.Fatalf("Cannot create temporary file: %v", err)
+ }
+ defer fd.Close()
+ defer os.Remove(fd.Name())
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ b.Fatalf("Cannot form new request: %v", err)
+ }
+
+ hashMethod := crypto.SHA256
+ buf := make([]byte, 1024)
+ client := &http.Client{}
+
+ b.ResetTimer()
+ for range b.N {
+ if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ b.Fatalf("Seek error: %v", err)
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ b.Fatalf("Request error: %v", err)
+ }
+ hw := hashMethod.New()
+ if _, err := io.CopyBuffer(io.MultiWriter(fd, hw), resp.Body, buf); err != nil {
+ b.Fatalf("Copy error: %v", err)
+ }
+ resp.Body.Close()
+ if hs := hw.Sum(buf[:0]); !bytes.Equal(hs, expectedDownloadHash) {
+ b.Fatalf("Hash mismatch: %#v", hs)
+ }
+ }
+}
+
+func BenchmarkDownlaodThenVerify(b *testing.B) {
+ url := startServer()
+ fd, err := os.CreateTemp("", "gotest-")
+ if err != nil {
+ b.Fatalf("Cannot create temporary file: %v", err)
+ }
+ defer fd.Close()
+ defer os.Remove(fd.Name())
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ b.Fatalf("Cannot form new request: %v", err)
+ }
+
+ hashMethod := crypto.SHA256
+ buf := make([]byte, 1024)
+ client := &http.Client{}
+
+ b.ResetTimer()
+ for range b.N {
+ if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ b.Fatalf("Seek error: %v", err)
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ b.Fatalf("Request error: %v", err)
+ }
+ if _, err := io.CopyBuffer(fd, resp.Body, buf); err != nil {
+ b.Fatalf("Copy error: %v", err)
+ }
+ resp.Body.Close()
+ hw := hashMethod.New()
+ if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ b.Fatalf("Seek error: %v", err)
+ }
+ if _, err := io.CopyBuffer(hw, fd, buf); err != nil {
+ b.Fatalf("Copy error: %v", err)
+ }
+ if hs := hw.Sum(buf[:0]); !bytes.Equal(hs, expectedDownloadHash) {
+ b.Fatalf("Hash mismatch: %#v", hs)
+ }
+ }
+}
diff --git a/cluster/tempfile_test.go b/cluster/tempfile_test.go
new file mode 100644
index 00000000..a2ad6ab1
--- /dev/null
+++ b/cluster/tempfile_test.go
@@ -0,0 +1,180 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package cluster_test
+
+import (
+ "testing"
+
+ "io"
+ "os"
+)
+
+var datas = func() [][]byte {
+ datas := make([][]byte, 0x7)
+ for i := range len(datas) {
+ b := make([]byte, 0xff00+i)
+ for j := range len(b) {
+ b[j] = (byte)(i + j)
+ }
+ datas[i] = b
+ }
+ return datas
+}()
+
+func BenchmarkCreateAndRemoveFile(b *testing.B) {
+ b.ReportAllocs()
+ buf := make([]byte, 1024)
+ _ = buf
+ for i := 0; i < b.N; i++ {
+ d := datas[i%len(datas)]
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ if _, err = fd.Write(d); err != nil {
+ b.Errorf("Cannot write file: %v", err)
+ } else if err = fd.Sync(); err != nil {
+ b.Errorf("Cannot write file: %v", err)
+ }
+ fd.Close()
+ os.Remove(fd.Name())
+ if err != nil {
+ b.FailNow()
+ }
+ }
+}
+
+func BenchmarkWriteAndTruncateFile(b *testing.B) {
+ b.ReportAllocs()
+ buf := make([]byte, 1024)
+ _ = buf
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ defer os.Remove(fd.Name())
+ for i := 0; i < b.N; i++ {
+ d := datas[i%len(datas)]
+ if _, err := fd.Write(d); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Sync(); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Truncate(0); err != nil {
+ b.Fatalf("Cannot truncate file: %v", err)
+ }
+ }
+}
+
+func BenchmarkWriteAndSeekFile(b *testing.B) {
+ b.ReportAllocs()
+ buf := make([]byte, 1024)
+ _ = buf
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ defer os.Remove(fd.Name())
+ for i := 0; i < b.N; i++ {
+ d := datas[i%len(datas)]
+ if _, err := fd.Write(d); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Sync(); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ b.Fatalf("Cannot seek file: %v", err)
+ }
+ }
+}
+
+func BenchmarkParallelCreateAndRemoveFile(b *testing.B) {
+ b.ReportAllocs()
+ b.SetParallelism(4)
+ buf := make([]byte, 1024)
+ _ = buf
+ b.RunParallel(func(pb *testing.PB) {
+ for i := 0; pb.Next(); i++ {
+ d := datas[i%len(datas)]
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ if _, err = fd.Write(d); err != nil {
+ b.Errorf("Cannot write file: %v", err)
+ } else if err = fd.Sync(); err != nil {
+ b.Errorf("Cannot write file: %v", err)
+ }
+ fd.Close()
+ if err := os.Remove(fd.Name()); err != nil {
+ b.Fatalf("Cannot remove file: %v", err)
+ }
+ if err != nil {
+ b.FailNow()
+ }
+ }
+ })
+}
+
+func BenchmarkParallelWriteAndTruncateFile(b *testing.B) {
+ b.ReportAllocs()
+ b.SetParallelism(4)
+ buf := make([]byte, 1024)
+ _ = buf
+ b.RunParallel(func(pb *testing.PB) {
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ defer os.Remove(fd.Name())
+ for i := 0; pb.Next(); i++ {
+ d := datas[i%len(datas)]
+ if _, err := fd.Write(d); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Sync(); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Truncate(0); err != nil {
+ b.Fatalf("Cannot truncate file: %v", err)
+ }
+ }
+ })
+}
+
+func BenchmarkParallelWriteAndSeekFile(b *testing.B) {
+ b.ReportAllocs()
+ b.SetParallelism(4)
+ buf := make([]byte, 1024)
+ _ = buf
+ b.RunParallel(func(pb *testing.PB) {
+ fd, err := os.CreateTemp("", "*.downloading")
+ if err != nil {
+ b.Fatalf("Cannot create temp file: %v", err)
+ }
+ defer os.Remove(fd.Name())
+ for i := 0; pb.Next(); i++ {
+ d := datas[i%len(datas)]
+ if _, err := fd.Write(d); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if err := fd.Sync(); err != nil {
+ b.Fatalf("Cannot write file: %v", err)
+ } else if _, err := fd.Seek(io.SeekStart, 0); err != nil {
+ b.Fatalf("Cannot seel file: %v", err)
+ }
+ }
+ })
+}
diff --git a/config.go b/config.go
index e3ddb66c..5d178ffb 100644
--- a/config.go
+++ b/config.go
@@ -1,6 +1,6 @@
/**
* OpenBmclAPI (Golang Edition)
- * Copyright (C) 2023 Kevin Z
+ * Copyright (C) 2024 Kevin Z
* All rights reserved
*
* This program is free software: you can redistribute it and/or modify
@@ -21,354 +21,94 @@ package main
import (
"bytes"
+ "context"
+ "encoding/json"
"errors"
"fmt"
- "net/url"
"os"
- "path/filepath"
- "regexp"
- "strconv"
"strings"
- "time"
+ "sync"
"gopkg.in/yaml.v3"
- "github.com/LiterMC/go-openbmclapi/cache"
- "github.com/LiterMC/go-openbmclapi/limited"
+ "github.com/LiterMC/go-openbmclapi/api"
+ "github.com/LiterMC/go-openbmclapi/cluster"
+ "github.com/LiterMC/go-openbmclapi/config"
"github.com/LiterMC/go-openbmclapi/log"
"github.com/LiterMC/go-openbmclapi/storage"
- "github.com/LiterMC/go-openbmclapi/utils"
)
-type UserItem struct {
- Username string `yaml:"username"`
- Password string `yaml:"password"`
-}
-
-type AdvancedConfig struct {
- DebugLog bool `yaml:"debug-log"`
- SocketIOLog bool `yaml:"socket-io-log"`
- NoHeavyCheck bool `yaml:"no-heavy-check"`
- NoGC bool `yaml:"no-gc"`
- HeavyCheckInterval int `yaml:"heavy-check-interval"`
- KeepaliveTimeout int `yaml:"keepalive-timeout"`
- SkipFirstSync bool `yaml:"skip-first-sync"`
- SkipSignatureCheck bool `yaml:"skip-signature-check"`
- NoFastEnable bool `yaml:"no-fast-enable"`
- WaitBeforeEnable int `yaml:"wait-before-enable"`
-
- DoNotRedirectHTTPSToSecureHostname bool `yaml:"do-NOT-redirect-https-to-SECURE-hostname"`
- DoNotOpenFAQOnWindows bool `yaml:"do-not-open-faq-on-windows"`
-}
-
-type CertificateConfig struct {
- Cert string `yaml:"cert"`
- Key string `yaml:"key"`
-}
-
-type ServeLimitConfig struct {
- Enable bool `yaml:"enable"`
- MaxConn int `yaml:"max-conn"`
- UploadRate int `yaml:"upload-rate"`
-}
-
-type APIRateLimitConfig struct {
- Anonymous limited.RateLimit `yaml:"anonymous"`
- Logged limited.RateLimit `yaml:"logged"`
-}
-
-type NotificationConfig struct {
- EnableEmail bool `yaml:"enable-email"`
- EmailSMTP string `yaml:"email-smtp"`
- EmailSMTPEncryption string `yaml:"email-smtp-encryption"`
- EmailSender string `yaml:"email-sender"`
- EmailSenderPassword string `yaml:"email-sender-password"`
- EnableWebhook bool `yaml:"enable-webhook"`
-}
-
-type DatabaseConfig struct {
- Driver string `yaml:"driver"`
- DSN string `yaml:"data-source-name"`
-}
-
-type HijackConfig struct {
- Enable bool `yaml:"enable"`
- EnableLocalCache bool `yaml:"enable-local-cache"`
- LocalCachePath string `yaml:"local-cache-path"`
- RequireAuth bool `yaml:"require-auth"`
- AuthUsers []UserItem `yaml:"auth-users"`
-}
-
-type CacheConfig struct {
- Type string `yaml:"type"`
- Data any `yaml:"data,omitempty"`
-
- newCache func() cache.Cache `yaml:"-"`
-}
-
-func (c *CacheConfig) UnmarshalYAML(n *yaml.Node) (err error) {
- var cfg struct {
- Type string `yaml:"type"`
- Data utils.RawYAML `yaml:"data,omitempty"`
- }
- if err = n.Decode(&cfg); err != nil {
- return
- }
- c.Type = cfg.Type
- c.Data = nil
- switch strings.ToLower(c.Type) {
- case "no", "off", "disabled", "nocache", "no-cache":
- c.newCache = func() cache.Cache { return cache.NoCache }
- case "mem", "memory", "inmem":
- c.newCache = func() cache.Cache { return cache.NewInMemCache() }
- case "redis":
- opt := new(cache.RedisOptions)
- if err = cfg.Data.Decode(opt); err != nil {
- return
- }
- c.Data = opt
- c.newCache = func() cache.Cache { return cache.NewRedisCache(opt.ToRedis()) }
- default:
- return fmt.Errorf("Unexpected cache type %q", c.Type)
- }
- return nil
-}
-
-type GithubAPIConfig struct {
- UpdateCheckInterval utils.YAMLDuration `yaml:"update-check-interval"`
- Authorization string `yaml:"authorization"`
-}
-
-type DashboardConfig struct {
- Enable bool `yaml:"enable"`
- Username string `yaml:"username"`
- Password string `yaml:"password"`
- PwaName string `yaml:"pwa-name"`
- PwaShortName string `yaml:"pwa-short_name"`
- PwaDesc string `yaml:"pwa-description"`
-
- NotifySubject string `yaml:"notification-subject"`
-}
-
-type TunnelConfig struct {
- Enable bool `yaml:"enable"`
- TunnelProg string `yaml:"tunnel-program"`
- OutputRegex string `yaml:"output-regex"`
- TunnelTimeout int `yaml:"tunnel-timeout"`
-
- outputRegex *regexp.Regexp
- hostOut int
- portOut int
-}
-
-func (c *TunnelConfig) UnmarshalYAML(n *yaml.Node) (err error) {
- type T TunnelConfig
- if err = n.Decode((*T)(c)); err != nil {
- return
- }
- if !c.Enable {
- return
- }
- if c.outputRegex, err = regexp.Compile(c.OutputRegex); err != nil {
- return
- }
- c.hostOut = c.outputRegex.SubexpIndex("host")
- c.portOut = c.outputRegex.SubexpIndex("port")
- if c.hostOut <= 0 {
- return errors.New("tunneler.output-regex: missing named `(?)` capture group")
- }
- if c.portOut <= 0 {
- return errors.New("tunneler.output-regex: missing named `(?)` capture group")
- }
- return
-}
-
-type Config struct {
- LogSlots int `yaml:"log-slots"`
- NoAccessLog bool `yaml:"no-access-log"`
- AccessLogSlots int `yaml:"access-log-slots"`
- Byoc bool `yaml:"byoc"`
- UseCert bool `yaml:"use-cert"`
- TrustedXForwardedFor bool `yaml:"trusted-x-forwarded-for"`
- PublicHost string `yaml:"public-host"`
- PublicPort uint16 `yaml:"public-port"`
- Port uint16 `yaml:"port"`
- ClusterId string `yaml:"cluster-id"`
- ClusterSecret string `yaml:"cluster-secret"`
- SyncInterval int `yaml:"sync-interval"`
- OnlyGcWhenStart bool `yaml:"only-gc-when-start"`
- DownloadMaxConn int `yaml:"download-max-conn"`
- MaxReconnectCount int `yaml:"max-reconnect-count"`
-
- Certificates []CertificateConfig `yaml:"certificates"`
- Tunneler TunnelConfig `yaml:"tunneler"`
- Cache CacheConfig `yaml:"cache"`
- ServeLimit ServeLimitConfig `yaml:"serve-limit"`
- RateLimit APIRateLimitConfig `yaml:"api-rate-limit"`
- Notification NotificationConfig `yaml:"notification"`
- Dashboard DashboardConfig `yaml:"dashboard"`
- GithubAPI GithubAPIConfig `yaml:"github-api"`
- Database DatabaseConfig `yaml:"database"`
- Hijack HijackConfig `yaml:"hijack"`
- Storages []storage.StorageOption `yaml:"storages"`
- WebdavUsers map[string]*storage.WebDavUser `yaml:"webdav-users"`
- Advanced AdvancedConfig `yaml:"advanced"`
-}
-
-func (cfg *Config) applyWebManifest(manifest map[string]any) {
- if cfg.Dashboard.Enable {
- manifest["name"] = cfg.Dashboard.PwaName
- manifest["short_name"] = cfg.Dashboard.PwaShortName
- manifest["description"] = cfg.Dashboard.PwaDesc
- }
-}
-
-var defaultConfig = Config{
- LogSlots: 7,
- NoAccessLog: false,
- AccessLogSlots: 16,
- Byoc: false,
- TrustedXForwardedFor: false,
- PublicHost: "",
- PublicPort: 0,
- Port: 4000,
- ClusterId: "${CLUSTER_ID}",
- ClusterSecret: "${CLUSTER_SECRET}",
- SyncInterval: 10,
- OnlyGcWhenStart: false,
- DownloadMaxConn: 16,
- MaxReconnectCount: 10,
-
- Certificates: []CertificateConfig{
- {
- Cert: "/path/to/cert.pem",
- Key: "/path/to/key.pem",
- },
- },
-
- Tunneler: TunnelConfig{
- Enable: false,
- TunnelProg: "./path/to/tunnel/program",
- OutputRegex: `\bNATedAddr\s+(?P[0-9.]+|\[[0-9a-f:]+\]):(?P\d+)$`,
- TunnelTimeout: 0,
- },
-
- Cache: CacheConfig{
- Type: "inmem",
- newCache: func() cache.Cache { return cache.NewInMemCache() },
- },
-
- ServeLimit: ServeLimitConfig{
- Enable: false,
- MaxConn: 16384,
- UploadRate: 1024 * 12, // 12MB
- },
-
- RateLimit: APIRateLimitConfig{
- Anonymous: limited.RateLimit{
- PerMin: 10,
- PerHour: 120,
- },
- Logged: limited.RateLimit{
- PerMin: 120,
- PerHour: 6000,
- },
- },
-
- Notification: NotificationConfig{
- EnableEmail: false,
- EmailSMTP: "smtp.example.com:25",
- EmailSMTPEncryption: "tls",
- EmailSender: "noreply@example.com",
- EmailSenderPassword: "example-password",
- EnableWebhook: true,
- },
-
- Dashboard: DashboardConfig{
- Enable: true,
- PwaName: "GoOpenBmclApi Dashboard",
- PwaShortName: "GOBA Dash",
- PwaDesc: "Go-Openbmclapi Internal Dashboard",
- NotifySubject: "mailto:user@example.com",
- },
-
- GithubAPI: GithubAPIConfig{
- UpdateCheckInterval: (utils.YAMLDuration)(time.Hour),
- },
-
- Database: DatabaseConfig{
- Driver: "sqlite",
- DSN: filepath.Join("data", "files.db"),
- },
-
- Hijack: HijackConfig{
- Enable: false,
- RequireAuth: false,
- EnableLocalCache: false,
- LocalCachePath: "hijack_cache",
- AuthUsers: []UserItem{
- {
- Username: "example-username",
- Password: "example-password",
- },
- },
- },
-
- Storages: nil,
-
- WebdavUsers: map[string]*storage.WebDavUser{},
-
- Advanced: AdvancedConfig{
- DebugLog: false,
- NoHeavyCheck: false,
- NoGC: false,
- HeavyCheckInterval: 120,
- KeepaliveTimeout: 10,
- SkipFirstSync: false,
- NoFastEnable: false,
- WaitBeforeEnable: 0,
- },
-}
-
-func migrateConfig(data []byte, config *Config) {
+func migrateConfig(data []byte, cfg *config.Config) {
var oldConfig map[string]any
if err := yaml.Unmarshal(data, &oldConfig); err != nil {
return
}
if v, ok := oldConfig["debug"].(bool); ok {
- config.Advanced.DebugLog = v
+ cfg.Advanced.DebugLog = v
}
if v, ok := oldConfig["no-heavy-check"].(bool); ok {
- config.Advanced.NoHeavyCheck = v
+ cfg.Advanced.NoHeavyCheck = v
}
if v, ok := oldConfig["keepalive-timeout"].(int); ok {
- config.Advanced.KeepaliveTimeout = v
+ cfg.Advanced.KeepaliveTimeout = v
+ }
+ if oldConfig["clusters"] == nil {
+ id, ok1 := oldConfig["cluster-id"].(string)
+ secret, ok2 := oldConfig["cluster-secret"].(string)
+ publicHost, ok3 := oldConfig["public-host"].(string)
+ if ok1 && ok2 && ok3 {
+ cfg.Clusters = map[string]config.ClusterOptions{
+ "main": {
+ Id: id,
+ Secret: secret,
+ PublicHosts: []string{publicHost},
+ },
+ }
+ }
}
}
-func readConfig() (config Config) {
+func readAndRewriteConfig() (cfg *config.Config, err error) {
const configPath = "config.yaml"
- config = defaultConfig
-
+ cfg = config.NewDefaultConfig()
data, err := os.ReadFile(configPath)
notexists := false
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
- log.Errorf(Tr("error.config.read.failed"), err)
- osExit(CodeClientError)
+ log.TrErrorf("error.config.read.failed", err)
+ os.Exit(1)
}
- log.Error(Tr("error.config.not.exists"))
+ log.TrErrorf("error.config.not.exists")
notexists = true
} else {
- migrateConfig(data, &config)
- if err = yaml.Unmarshal(data, &config); err != nil {
- log.Errorf(Tr("error.config.parse.failed"), err)
- osExit(CodeClientError)
+ migrateConfig(data, cfg)
+ if err = cfg.UnmarshalText(data); err != nil {
+ log.TrErrorf("error.config.parse.failed", err)
+ os.Exit(1)
+ }
+ if len(cfg.Clusters) == 0 {
+ cfg.Clusters = map[string]config.ClusterOptions{
+ "main": {
+ Id: "${CLUSTER_ID}",
+ Secret: "${CLUSTER_SECRET}",
+ PublicHosts: []string{},
+ Server: cluster.DefaultBMCLAPIServer,
+ SkipSignatureCheck: false,
+ },
+ }
+ }
+ if len(cfg.Certificates) == 0 {
+ cfg.Certificates = []config.CertificateConfig{
+ {
+ Cert: "/path/to/cert.pem",
+ Key: "/path/to/key.pem",
+ },
+ }
}
- if len(config.Storages) == 0 {
- config.Storages = []storage.StorageOption{
+ if len(cfg.Storages) == 0 {
+ cfg.Storages = []storage.StorageOption{
{
BasicStorageOption: storage.BasicStorageOption{
Id: "local",
@@ -381,109 +121,192 @@ func readConfig() (config Config) {
},
}
}
- if len(config.WebdavUsers) == 0 {
- config.WebdavUsers["example-user"] = &storage.WebDavUser{
+ if len(cfg.WebdavUsers) == 0 {
+ cfg.WebdavUsers["example-user"] = &storage.WebDavUser{
EndPoint: "https://webdav.example.com/path/to/endpoint/",
Username: "example-username",
Password: "example-password",
}
}
- ids := make(map[string]int, len(config.Storages))
- for i, s := range config.Storages {
+ ids := make(map[string]int, len(cfg.Storages))
+ for i, s := range cfg.Storages {
if s.Id == "" {
s.Id = fmt.Sprintf("storage-%d", i)
- config.Storages[i].Id = s.Id
+ cfg.Storages[i].Id = s.Id
}
if j, ok := ids[s.Id]; ok {
log.Errorf("Duplicated storage id %q at [%d] and [%d], please edit the config.", s.Id, i, j)
- osExit(CodeClientError)
+ os.Exit(1)
}
ids[s.Id] = i
}
}
- for _, so := range config.Storages {
- switch opt := so.Data.(type) {
- case *storage.WebDavStorageOption:
- if alias := opt.Alias; alias != "" {
- user, ok := config.WebdavUsers[alias]
- if !ok {
- log.Errorf(Tr("error.config.alias.user.not.exists"), alias)
- osExit(CodeClientError)
- }
- opt.AliasUser = user
- var end *url.URL
- if end, err = url.Parse(opt.AliasUser.EndPoint); err != nil {
- return
- }
- if opt.EndPoint != "" {
- var full *url.URL
- if full, err = end.Parse(opt.EndPoint); err != nil {
- return
- }
- opt.FullEndPoint = full.String()
- } else {
- opt.FullEndPoint = opt.AliasUser.EndPoint
- }
- } else {
- opt.FullEndPoint = opt.EndPoint
- }
- }
- }
-
var buf bytes.Buffer
encoder := yaml.NewEncoder(&buf)
encoder.SetIndent(2)
- if err = encoder.Encode(config); err != nil {
- log.Errorf(Tr("error.config.encode.failed"), err)
- osExit(CodeClientError)
+ if err = encoder.Encode(cfg); err != nil {
+ log.TrErrorf("error.config.encode.failed", err)
+ os.Exit(1)
}
if err = os.WriteFile(configPath, buf.Bytes(), 0600); err != nil {
- log.Errorf(Tr("error.config.write.failed"), err)
- osExit(CodeClientError)
+ log.TrErrorf("error.config.write.failed", err)
+ os.Exit(1)
}
if notexists {
- log.Error(Tr("error.config.created"))
- osExit(0xff)
+ log.TrErrorf("error.config.created")
+ return nil, errors.New("Please edit the config before continue!")
}
+ return
+}
+
+type ConfigHandler struct {
+ mux sync.RWMutex
+ r *Runner
+
+ updateProcess []func(context.Context) error
+}
+
+var _ api.ConfigHandler = (*ConfigHandler)(nil)
+
+func (c *ConfigHandler) GetConfig() *config.Config {
+ return c.r.Config
+}
- if os.Getenv("DEBUG") == "true" {
- config.Advanced.DebugLog = true
+func (c *ConfigHandler) update(newConfig *config.Config) error {
+ r := c.r
+ oldConfig := r.Config
+ c.updateProcess = c.updateProcess[:0]
+
+ if newConfig.LogSlots != oldConfig.LogSlots || newConfig.NoAccessLog != oldConfig.NoAccessLog || newConfig.AccessLogSlots != oldConfig.AccessLogSlots || newConfig.Advanced.DebugLog != oldConfig.Advanced.DebugLog {
+ c.updateProcess = append(c.updateProcess, r.SetupLogger)
+ }
+ if newConfig.Host != oldConfig.Host || newConfig.Port != oldConfig.Port {
+ c.updateProcess = append(c.updateProcess, r.StartServer)
+ }
+ if newConfig.PublicHost != oldConfig.PublicHost || newConfig.PublicPort != oldConfig.PublicPort || newConfig.Advanced.NoFastEnable != oldConfig.Advanced.NoFastEnable || newConfig.MaxReconnectCount != oldConfig.MaxReconnectCount {
+ c.updateProcess = append(c.updateProcess, r.updateClustersWithGeneralConfig)
+ }
+ if newConfig.RateLimit != oldConfig.RateLimit {
+ c.updateProcess = append(c.updateProcess, r.updateRateLimit)
}
- if v := os.Getenv("CLUSTER_IP"); v != "" {
- config.PublicHost = v
+ if newConfig.Notification != oldConfig.Notification {
+ // c.updateProcess = append(c.updateProcess, )
}
- if v := os.Getenv("CLUSTER_PORT"); v != "" {
- if n, err := strconv.Atoi(v); err != nil {
- log.Errorf("Cannot parse CLUSTER_PORT %q: %v", v, err)
- } else {
- config.Port = (uint16)(n)
+
+ r.Config = newConfig
+ r.publicHost = r.Config.PublicHost
+ r.publicPort = r.Config.PublicPort
+ return nil
+}
+
+func (c *ConfigHandler) doUpdateProcesses(ctx context.Context) error {
+ for _, proc := range c.updateProcess {
+ if err := proc(ctx); err != nil {
+ return err
}
}
- if v := os.Getenv("CLUSTER_PUBLIC_PORT"); v != "" {
- if n, err := strconv.Atoi(v); err != nil {
- log.Errorf("Cannot parse CLUSTER_PUBLIC_PORT %q: %v", v, err)
- } else {
- config.PublicPort = (uint16)(n)
+ c.updateProcess = c.updateProcess[:0]
+ return nil
+}
+
+func (c *ConfigHandler) MarshalJSON() ([]byte, error) {
+ c.mux.RLock()
+ defer c.mux.RUnlock()
+ return c.marshalJSONLocked()
+}
+
+func (c *ConfigHandler) marshalJSONLocked() ([]byte, error) {
+ return c.r.Config.MarshalJSON()
+}
+
+func (c *ConfigHandler) UnmarshalJSON(data []byte) error {
+ c2 := c.r.Config.Clone()
+ if err := c2.UnmarshalJSON(data); err != nil {
+ return err
+ }
+ c.update(c2)
+ return nil
+}
+
+func (c *ConfigHandler) UnmarshalYAML(data []byte) error {
+ c2 := c.r.Config.Clone()
+ if err := c2.UnmarshalText(data); err != nil {
+ return err
+ }
+ c.update(c2)
+ return nil
+}
+
+func (c *ConfigHandler) MarshalJSONPath(path string) ([]byte, error) {
+ names := strings.Split(path, ".")
+ data, err := c.MarshalJSON()
+ if err != nil {
+ return nil, err
+ }
+ var m map[string]any
+ if err := json.Unmarshal(data, &m); err != nil {
+ return nil, err
+ }
+ accessed := ""
+ var x any = m
+ for _, n := range names {
+ mc, ok := x.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("Unexpected type %T on path %q, expect map[string]any", x, accessed)
}
+ accessed += n + "."
+ x = mc[n]
+ }
+ buf, err := json.Marshal(x)
+ if err != nil {
+ return nil, err
}
- if v := os.Getenv("CLUSTER_ID"); v != "" {
- config.ClusterId = v
+ return buf, nil
+}
+
+func (c *ConfigHandler) UnmarshalJSONPath(path string, data []byte) error {
+ names := strings.Split(path, ".")
+ var d any
+ if err := json.Unmarshal(data, &d); err != nil {
+ return err
+ }
+ accessed := ""
+ var m map[string]any
+ {
+ b, err := c.MarshalJSON()
+ if err != nil {
+ return err
+ }
+ if err := json.Unmarshal(b, &m); err != nil {
+ return err
+ }
}
- if v := os.Getenv("CLUSTER_SECRET"); v != "" {
- config.ClusterSecret = v
+ x := m
+ for _, p := range names[:len(names)-1] {
+ accessed += p + "."
+ var ok bool
+ x, ok = x[p].(map[string]any)
+ if !ok {
+ return fmt.Errorf("Unexpected type %T on path %q, expect map[string]any", x, accessed)
+ }
}
- if byoc := os.Getenv("CLUSTER_BYOC"); byoc != "" {
- config.Byoc = byoc == "true"
+ x[names[len(names)-1]] = d
+ dt, err := json.Marshal(m)
+ if err != nil {
+ return err
}
- return
+ return c.UnmarshalJSON(dt)
}
-type OpenbmclapiAgentSyncConfig struct {
- Source string `json:"source"`
- Concurrency int `json:"concurrency"`
+func (c *ConfigHandler) DoReadLockedAction(callback func(api.ConfigHandler) error) error {
+ c.mux.RLock()
+ defer c.mux.RUnlock()
+ return callback(c)
}
-type OpenbmclapiAgentConfig struct {
- Sync OpenbmclapiAgentSyncConfig `json:"sync"`
+func (c *ConfigHandler) DoWriteLockedAction(callback func(api.ConfigHandler) error) error {
+ c.mux.Lock()
+ defer c.mux.Unlock()
+ return callback(c)
}
diff --git a/config.yaml b/config.yaml
index ea91ef80..3cc54dda 100644
--- a/config.yaml
+++ b/config.yaml
@@ -1,18 +1,33 @@
-log-slots: 7
-no-access-log: false
-access-log-slots: 16
-byoc: false
-use-cert: false
-trusted-x-forwarded-for: false
public-host: ""
public-port: 0
+host: 0.0.0.0
port: 4000
-cluster-id: ${CLUSTER_ID}
-cluster-secret: ${CLUSTER_SECRET}
-sync-interval: 10
+use-cert: false
+trusted-x-forwarded-for: false
only-gc-when-start: false
+sync-interval: 10
download-max-conn: 16
max-reconnect-count: 10
+log-slots: 7
+no-access-log: false
+access-log-slots: 16
+clusters:
+ main:
+ id: ${CLUSTER_ID}
+ secret: ${CLUSTER_SECRET}
+ byoc: false
+ public-hosts:
+ - ""
+ server: ""
+ skip-signature-check: false
+ storages: []
+storages:
+ - type: local
+ id: local-storage-0
+ weight: 100
+ data:
+ cache-path: _cache
+ compressor: ""
certificates:
- cert: /path/to/cert.pem
key: /path/to/key.pem
@@ -20,7 +35,6 @@ tunneler:
enable: false
tunnel-program: ./path/to/tunnel/program
output-regex: \bNATedAddr\s+(?[0-9.]+|\[[0-9a-f:]+\]):(?\d+)$
- tunnel-timeout: 0
cache:
type: inmem
serve-limit:
@@ -63,13 +77,6 @@ hijack:
auth-users:
- username: example-username
password: example-password
-storages:
- - type: local
- id: local-storage-0
- weight: 100
- data:
- cache-path: _cache
- compressor: ""
webdav-users:
example-user:
endpoint: https://webdav.example.com/path/to/endpoint/
@@ -82,9 +89,6 @@ advanced:
no-gc: false
heavy-check-interval: 120
keepalive-timeout: 10
- skip-first-sync: false
- skip-signature-check: false
no-fast-enable: false
wait-before-enable: 0
- do-NOT-redirect-https-to-SECURE-hostname: false
do-not-open-faq-on-windows: false
diff --git a/config/advanced.go b/config/advanced.go
new file mode 100644
index 00000000..99fc1320
--- /dev/null
+++ b/config/advanced.go
@@ -0,0 +1,34 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package config
+
+type AdvancedConfig struct {
+ DebugLog bool `yaml:"debug-log"`
+ SocketIOLog bool `yaml:"socket-io-log"`
+ NoHeavyCheck bool `yaml:"no-heavy-check"`
+ NoGC bool `yaml:"no-gc"`
+ HeavyCheckInterval int `yaml:"heavy-check-interval"`
+ KeepaliveTimeout int `yaml:"keepalive-timeout"`
+ NoFastEnable bool `yaml:"no-fast-enable"`
+ WaitBeforeEnable int `yaml:"wait-before-enable"`
+
+ // DoNotRedirectHTTPSToSecureHostname bool `yaml:"do-NOT-redirect-https-to-SECURE-hostname"`
+ DoNotOpenFAQOnWindows bool `yaml:"do-not-open-faq-on-windows"`
+}
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 00000000..141bc9aa
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,209 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package config
+
+import (
+ "encoding/json"
+ "path/filepath"
+ "time"
+
+ "gopkg.in/yaml.v3"
+
+ "github.com/LiterMC/go-openbmclapi/cache"
+ "github.com/LiterMC/go-openbmclapi/limited"
+ "github.com/LiterMC/go-openbmclapi/storage"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type Config struct {
+ PublicHost string `json:"public_host" yaml:"public-host"`
+ PublicPort uint16 `json:"public_port" yaml:"public-port"`
+ Host string `json:"host" yaml:"host"`
+ Port uint16 `json:"port" yaml:"port"`
+ UseCert bool `json:"use_cert" yaml:"use-cert"`
+ AllowUnsecureConn bool `json:"allow_unsecure_connection" yaml:"allow-unsecure-connection"`
+ TrustedXForwardedFor bool `json:"trusted_x_forwarded_for" yaml:"trusted-x-forwarded-for"`
+
+ OnlyGcWhenStart bool `json:"only_gc_when_start" yaml:"only-gc-when-start"`
+ SyncInterval int `json:"sync_interval" yaml:"sync-interval"`
+ DownloadMaxConn int `json:"download_max_conn" yaml:"download-max-conn"`
+ MaxReconnectCount int `json:"max_reconnect_count" yaml:"max-reconnect-count"`
+
+ LogSlots int `json:"log_slots" yaml:"log-slots"`
+ NoAccessLog bool `json:"no_access_log" yaml:"no-access-log"`
+ AccessLogSlots int `json:"access_log_slots" yaml:"access-log-slots"`
+
+ Clusters map[string]ClusterOptions `json:"clusters" yaml:"clusters"`
+ Storages []storage.StorageOption `json:"storages" yaml:"storages"`
+ Certificates []CertificateConfig `json:"certificates" yaml:"certificates"`
+ Tunneler TunnelConfig `json:"tunneler" yaml:"tunneler"`
+ Cache CacheConfig `json:"cache" yaml:"cache"`
+ ServeLimit ServeLimitConfig `json:"serve_limit" yaml:"serve-limit"`
+ RateLimit APIRateLimitConfig `json:"api_rate_limit" yaml:"api-rate-limit"`
+ Notification NotificationConfig `json:"notification" yaml:"notification"`
+ Dashboard DashboardConfig `json:"dashboard" yaml:"dashboard"`
+ GithubAPI GithubAPIConfig `json:"github_api" yaml:"github-api"`
+ Database DatabaseConfig `json:"database" yaml:"database"`
+ Hijack HijackConfig `json:"hijack" yaml:"hijack"`
+ WebdavUsers map[string]*storage.WebDavUser `json:"webdav_users" yaml:"webdav-users"`
+ Advanced AdvancedConfig `json:"advanced" yaml:"advanced"`
+}
+
+func (cfg *Config) ApplyWebManifest(manifest map[string]any) {
+ if cfg.Dashboard.Enable {
+ manifest["name"] = cfg.Dashboard.PwaName
+ manifest["short_name"] = cfg.Dashboard.PwaShortName
+ manifest["description"] = cfg.Dashboard.PwaDesc
+ }
+}
+
+func NewDefaultConfig() *Config {
+ return &Config{
+ PublicHost: "",
+ PublicPort: 443,
+ Host: "0.0.0.0",
+ Port: 4000,
+ UseCert: false,
+ TrustedXForwardedFor: false,
+
+ OnlyGcWhenStart: false,
+ SyncInterval: 10,
+ DownloadMaxConn: 16,
+ MaxReconnectCount: 10,
+
+ LogSlots: 7,
+ NoAccessLog: false,
+ AccessLogSlots: 16,
+
+ Clusters: map[string]ClusterOptions{},
+
+ Storages: nil,
+
+ Certificates: []CertificateConfig{},
+
+ Tunneler: TunnelConfig{
+ Enable: false,
+ TunnelProg: "./path/to/tunnel/program",
+ OutputRegex: `\bNATedAddr\s+(?P[0-9.]+|\[[0-9a-f:]+\]):(?P\d+)$`,
+ },
+
+ Cache: CacheConfig{
+ Type: "memory",
+ newCache: func() cache.Cache { return cache.NewInMemCache() },
+ },
+
+ ServeLimit: ServeLimitConfig{
+ Enable: false,
+ MaxConn: 16384,
+ UploadRate: 1024 * 12, // 12MB
+ },
+
+ RateLimit: APIRateLimitConfig{
+ Anonymous: limited.RateLimit{
+ PerMin: 10,
+ PerHour: 120,
+ },
+ Logged: limited.RateLimit{
+ PerMin: 120,
+ PerHour: 6000,
+ },
+ },
+
+ Notification: NotificationConfig{
+ EnableEmail: false,
+ EmailSMTP: "smtp.example.com:25",
+ EmailSMTPEncryption: "tls",
+ EmailSender: "noreply@example.com",
+ EmailSenderPassword: "example-password",
+ EnableWebhook: true,
+ },
+
+ Dashboard: DashboardConfig{
+ Enable: true,
+ Username: "",
+ Password: "",
+ PwaName: "GoOpenBmclApi Dashboard",
+ PwaShortName: "GOBA Dash",
+ PwaDesc: "Go-Openbmclapi Internal Dashboard",
+ NotifySubject: "mailto:user@example.com",
+ },
+
+ GithubAPI: GithubAPIConfig{
+ UpdateCheckInterval: (utils.YAMLDuration)(time.Hour),
+ Authorization: "",
+ },
+
+ Database: DatabaseConfig{
+ Driver: "sqlite",
+ DSN: filepath.Join("data", "files.db"),
+ },
+
+ Hijack: HijackConfig{
+ Enable: false,
+ EnableLocalCache: false,
+ LocalCachePath: "hijack_cache",
+ RequireAuth: false,
+ AuthUsers: []UserItem{
+ {
+ Username: "example-username",
+ Password: "example-password",
+ },
+ },
+ },
+
+ WebdavUsers: map[string]*storage.WebDavUser{},
+
+ Advanced: AdvancedConfig{
+ DebugLog: false,
+ NoHeavyCheck: false,
+ NoGC: false,
+ HeavyCheckInterval: 120,
+ KeepaliveTimeout: 10,
+ NoFastEnable: false,
+ WaitBeforeEnable: 0,
+ },
+ }
+}
+
+func (config *Config) MarshalJSON() ([]byte, error) {
+ type T Config
+ return json.Marshal((*T)(config))
+}
+
+func (config *Config) UnmarshalJSON(data []byte) error {
+ type T Config
+ return json.Unmarshal(data, (*T)(config))
+}
+
+func (config *Config) UnmarshalText(data []byte) error {
+ return yaml.Unmarshal(data, config)
+}
+
+func (config *Config) Clone() *Config {
+ data, err := config.MarshalJSON()
+ if err != nil {
+ panic(err)
+ }
+ cloned := new(Config)
+ if err := cloned.UnmarshalJSON(data); err != nil {
+ panic(err)
+ }
+ return cloned
+}
diff --git a/config/dashboard.go b/config/dashboard.go
new file mode 100644
index 00000000..6d35abdd
--- /dev/null
+++ b/config/dashboard.go
@@ -0,0 +1,49 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package config
+
+import (
+ "github.com/LiterMC/go-openbmclapi/limited"
+)
+
+type APIRateLimitConfig struct {
+ Anonymous limited.RateLimit `json:"anonymous" yaml:"anonymous"`
+ Logged limited.RateLimit `json:"logged" yaml:"logged"`
+}
+
+type NotificationConfig struct {
+ EnableEmail bool `json:"enable_email" yaml:"enable-email"`
+ EmailSMTP string `json:"email_smtp" yaml:"email-smtp"`
+ EmailSMTPEncryption string `json:"email_smtp_encryption" yaml:"email-smtp-encryption"`
+ EmailSender string `json:"email_sender" yaml:"email-sender"`
+ EmailSenderPassword string `json:"email_sender_password" yaml:"email-sender-password"`
+ EnableWebhook bool `json:"enable_webhook" yaml:"enable-webhook"`
+}
+
+type DashboardConfig struct {
+ Enable bool `json:"enable" yaml:"enable"`
+ Username string `json:"username" yaml:"username"`
+ Password string `json:"password" yaml:"password"`
+ PwaName string `json:"pwa_name" yaml:"pwa-name"`
+ PwaShortName string `json:"pwa_short_name" yaml:"pwa-short_name"`
+ PwaDesc string `json:"pwa_description" yaml:"pwa-description"`
+
+ NotifySubject string `json:"notification_subject" yaml:"notification-subject"`
+}
diff --git a/config/server.go b/config/server.go
new file mode 100644
index 00000000..17fa0a9b
--- /dev/null
+++ b/config/server.go
@@ -0,0 +1,161 @@
+/**
+ * OpenBmclAPI (Golang Edition)
+ * Copyright (C) 2024 Kevin Z
+ * All rights reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package config
+
+import (
+ "errors"
+ "fmt"
+ "regexp"
+
+ "gopkg.in/yaml.v3"
+
+ "github.com/LiterMC/go-openbmclapi/cache"
+ "github.com/LiterMC/go-openbmclapi/utils"
+)
+
+type ClusterOptions struct {
+ Id string `json:"id" yaml:"id"`
+ Secret string `json:"secret" yaml:"secret"`
+ Byoc bool `json:"byoc" yaml:"byoc"`
+ PublicHosts []string `json:"public_hosts" yaml:"public-hosts"`
+ Server string `json:"server" yaml:"server"`
+ SkipSignatureCheck bool `json:"skip_signature_check" yaml:"skip-signature-check"`
+ Storages []string `json:"storages" yaml:"storages"`
+}
+
+type ClusterGeneralConfig struct {
+ PublicHost string `json:"public_host"`
+ PublicPort uint16 `json:"public_port"`
+ NoFastEnable bool `json:"no_fast_enable"`
+ MaxReconnectCount int `json:"max_reconnect_count"`
+}
+
+type UserItem struct {
+ Username string `json:"username" yaml:"username"`
+ Password string `json:"password" yaml:"password"`
+}
+
+type CertificateConfig struct {
+ Cert string `json:"cert" yaml:"cert"`
+ Key string `json:"key" yaml:"key"`
+}
+
+type DatabaseConfig struct {
+ Driver string `json:"driver" yaml:"driver"`
+ DSN string `json:"data_source_name" yaml:"data-source-name"`
+}
+
+type HijackConfig struct {
+ Enable bool `json:"enable" yaml:"enable"`
+ EnableLocalCache bool `json:"enable_local_cache" yaml:"enable-local-cache"`
+ LocalCachePath string `json:"local_cache_path" yaml:"local-cache-path"`
+ RequireAuth bool `json:"require_auth" yaml:"require-auth"`
+ AuthUsers []UserItem `json:"auth_users" yaml:"auth-users"`
+}
+
+type CacheConfig struct {
+ Type string `json:"type" yaml:"type"`
+ Data any `json:"data" yaml:"data,omitempty"`
+
+ newCache func() cache.Cache `json:"-" yaml:"-"`
+}
+
+func (c *CacheConfig) NewCache() cache.Cache {
+ return c.newCache()
+}
+
+func (c *CacheConfig) UnmarshalYAML(n *yaml.Node) (err error) {
+ var cfg struct {
+ Type string `yaml:"type"`
+ Data utils.RawYAML `yaml:"data,omitempty"`
+ }
+ if err = n.Decode(&cfg); err != nil {
+ return
+ }
+ c.Type = cfg.Type
+ c.Data = nil
+ switch c.Type {
+ case "no-cache":
+ c.newCache = func() cache.Cache { return cache.NoCache }
+ case "memory":
+ c.newCache = func() cache.Cache { return cache.NewInMemCache() }
+ case "redis":
+ opt := new(cache.RedisOptions)
+ if err = cfg.Data.Decode(opt); err != nil {
+ return
+ }
+ c.Data = opt
+ c.newCache = func() cache.Cache { return cache.NewRedisCache(opt.ToRedis()) }
+ default:
+ return fmt.Errorf("Unexpected cache type %q", c.Type)
+ }
+ return nil
+}
+
+type ServeLimitConfig struct {
+ Enable bool `json:"enable" yaml:"enable"`
+ MaxConn int `json:"max_conn" yaml:"max-conn"`
+ UploadRate int `json:"upload_rate" yaml:"upload-rate"`
+}
+
+type GithubAPIConfig struct {
+ UpdateCheckInterval utils.YAMLDuration `json:"update_check_interval" yaml:"update-check-interval"`
+ Authorization string `json:"authorization" yaml:"authorization"`
+}
+
+type TunnelConfig struct {
+ Enable bool `json:"enable" yaml:"enable"`
+ TunnelProg string `json:"tunnel_program" yaml:"tunnel-program"`
+ OutputRegex string `json:"output_regex" yaml:"output-regex"`
+
+ outputRegex *regexp.Regexp
+ hostOut int
+ portOut int
+}
+
+func (c *TunnelConfig) UnmarshalYAML(n *yaml.Node) (err error) {
+ type T TunnelConfig
+ if err = n.Decode((*T)(c)); err != nil {
+ return
+ }
+ if !c.Enable {
+ return
+ }
+ if c.outputRegex, err = regexp.Compile(c.OutputRegex); err != nil {
+ return
+ }
+ c.hostOut = c.outputRegex.SubexpIndex("host")
+ c.portOut = c.outputRegex.SubexpIndex("port")
+ if c.hostOut <= 0 {
+ return errors.New("tunneler.output-regex: missing named `(?)` capture group")
+ }
+ if c.portOut <= 0 {
+ return errors.New("tunneler.output-regex: missing named `(?)` capture group")
+ }
+ return
+}
+
+func (c *TunnelConfig) MatchTunnelOutput(line []byte) (host, port []byte, ok bool) {
+ res := c.outputRegex.FindSubmatch(line)
+ if res == nil {
+ return
+ }
+ return res[c.hostOut], res[c.portOut], true
+}
diff --git a/dashboard.go b/dashboard.go
index b07b0e8f..ff7d99cb 100644
--- a/dashboard.go
+++ b/dashboard.go
@@ -31,6 +31,7 @@ import (
"path"
"strings"
+ "github.com/LiterMC/go-openbmclapi/internal/build"
"github.com/LiterMC/go-openbmclapi/utils"
)
@@ -60,13 +61,14 @@ var dsbManifest = func() (dsbManifest map[string]any) {
return
}()
-func (cr *Cluster) serveDashboard(rw http.ResponseWriter, req *http.Request, pth string) {
+func (r *Runner) serveDashboard(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet && req.Method != http.MethodHead {
rw.Header().Set("Allow", http.MethodGet+", "+http.MethodHead)
http.Error(rw, "405 Method Not Allowed", http.StatusMethodNotAllowed)
return
}
acceptEncoding := utils.SplitCSV(req.Header.Get("Accept-Encoding"))
+ pth := strings.TrimPrefix(req.URL.Path, "/")
switch pth {
case "":
break
@@ -78,7 +80,7 @@ func (cr *Cluster) serveDashboard(rw http.ResponseWriter, req *http.Request, pth
return
}
rw.Header().Set("Content-Type", "application/manifest+json")
- http.ServeContent(rw, req, "manifest.webmanifest", startTime, bytes.NewReader(buf))
+ http.ServeContent(rw, req, "manifest.webmanifest", build.StartAt, bytes.NewReader(buf))
return
case "sw.js":
// Must not cache service worker
@@ -111,15 +113,15 @@ func (cr *Cluster) serveDashboard(rw http.ResponseWriter, req *http.Request, pth
if _, err := io.Copy(gw, fd); err == nil {
if err = gw.Close(); err == nil {
rw.Header().Set("Content-Encoding", "gzip")
- http.ServeContent(rw, req, name, startTime, bytes.NewReader(buf.Bytes()))
+ http.ServeContent(rw, req, name, build.StartAt, bytes.NewReader(buf.Bytes()))
return
}
}
}
- http.ServeContent(rw, req, name, startTime, fd.(io.ReadSeeker))
+ http.ServeContent(rw, req, name, build.StartAt, fd.(io.ReadSeeker))
return
}
}
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
- http.ServeContent(rw, req, "index.html", startTime, strings.NewReader(dsbIndexHtml))
+ http.ServeContent(rw, req, "index.html", build.StartAt, strings.NewReader(dsbIndexHtml))
}
diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json
index 705512d6..223d133a 100644
--- a/dashboard/package-lock.json
+++ b/dashboard/package-lock.json
@@ -8,13 +8,14 @@
"name": "dashboard",
"version": "0.0.0",
"dependencies": {
+ "@primeuix/themes": "^1.0.1",
"@types/pako": "^2.0.3",
"axios": "^1.6.2",
"chart.js": "^4.4.1",
"js-sha256": "^0.11.0",
"pako": "^2.1.0",
"primeicons": "^6.0.1",
- "primevue": "^3.49.0",
+ "primevue": "^4.3.3",
"register-service-worker": "^1.7.2",
"vue": "^3.2.47",
"vue-cookies": "^1.8.3",
@@ -45,146 +46,72 @@
"workbox-window": "^7.0.0"
}
},
- "node_modules/@aashutoshrathi/word-wrap": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
- "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@antfu/utils": {
- "version": "0.7.7",
- "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.7.tgz",
- "integrity": "sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==",
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz",
+ "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
"dev": true,
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/code-frame/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/@babel/code-frame/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/@babel/code-frame/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/code-frame/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/@babel/compat-data": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
- "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
+ "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz",
- "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helpers": "^7.23.6",
- "@babel/parser": "^7.23.6",
- "@babel/template": "^7.22.15",
- "@babel/traverse": "^7.23.6",
- "@babel/types": "^7.23.6",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.10",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
+ "@babel/template": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -199,75 +126,56 @@
"url": "https://opencollective.com/babel"
}
},
- "node_modules/@babel/core/node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
- "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
+ "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.23.6",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
- "jsesc": "^2.5.1"
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
- "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz",
- "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.15"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
- "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz",
+ "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.23.5",
- "@babel/helper-validator-option": "^7.23.5",
- "browserslist": "^4.22.2",
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -275,44 +183,29 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
- "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
- },
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz",
- "integrity": "sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-member-expression-to-functions": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz",
+ "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.26.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/traverse": "^7.27.0",
"semver": "^6.3.1"
},
"engines": {
@@ -327,18 +220,20 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz",
- "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz",
+ "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "regexpu-core": "^5.3.1",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
"engines": {
@@ -353,15 +248,17 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz",
- "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz",
+ "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
@@ -373,75 +270,44 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz",
- "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+ "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.23.0"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
- "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.15"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
- "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/helper-validator-identifier": "^7.22.20"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -451,35 +317,38 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
- "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+ "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
- "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz",
- "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-wrap-function": "^7.22.20"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-wrap-function": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -489,14 +358,15 @@
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz",
- "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
+ "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-member-expression-to-functions": "^7.22.15",
- "@babel/helper-optimise-call-expression": "^7.22.5"
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/traverse": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -505,200 +375,133 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
- "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
- "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+ "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
- "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
- "dev": true,
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "dev": true,
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
- "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-wrap-function": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz",
- "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+ "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-function-name": "^7.22.5",
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.22.19"
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz",
- "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+ "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/traverse": "^7.23.6",
- "@babel/types": "^7.23.6"
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
- "dev": true,
+ "node_modules/@babel/parser": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+ "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "@babel/types": "^7.27.0"
},
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
+ "bin": {
+ "parser": "bin/babel-parser.js"
},
"engines": {
- "node": ">=4"
+ "node": ">=6.0.0"
}
},
- "node_modules/@babel/highlight/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+ "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/highlight/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/@babel/highlight/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/@babel/highlight/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/highlight/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+ "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-flag": "^3.0.0"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
- "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
- "bin": {
- "parser": "bin/babel-parser.js"
+ "node": ">=6.9.0"
},
- "engines": {
- "node": ">=6.0.0"
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz",
- "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+ "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -708,14 +511,15 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz",
- "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.23.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -725,13 +529,14 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz",
- "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+ "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -745,6 +550,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
},
@@ -752,76 +558,99 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+ "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
+ "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-remap-async-to-generator": "^7.25.9",
+ "@babel/traverse": "^7.26.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz",
- "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==",
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -830,13 +659,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz",
- "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==",
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
+ "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -845,279 +675,72 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz",
+ "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.26.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+ "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0-0"
+ "@babel/core": "^7.12.0"
}
},
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+ "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
- "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz",
- "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz",
- "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.20",
- "@babel/plugin-syntax-async-generators": "^7.8.4"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz",
- "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.20"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz",
- "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz",
- "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz",
- "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz",
- "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.12.0"
- }
- },
- "node_modules/@babel/plugin-transform-classes": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz",
- "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.22.15",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@@ -1128,18 +751,20 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz",
- "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+ "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/template": "^7.22.15"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/template": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1149,12 +774,13 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz",
- "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+ "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1164,13 +790,14 @@
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz",
- "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+ "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1180,12 +807,13 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz",
- "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+ "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1194,14 +822,31 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz",
- "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+ "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1211,13 +856,13 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz",
- "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+ "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1227,13 +872,13 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz",
- "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+ "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1243,13 +888,14 @@
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz",
- "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==",
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz",
+ "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1259,14 +905,15 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz",
- "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+ "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.22.15",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1276,13 +923,13 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz",
- "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+ "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1292,12 +939,13 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz",
- "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+ "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1307,13 +955,13 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz",
- "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+ "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1323,12 +971,13 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz",
- "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+ "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1338,13 +987,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz",
- "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+ "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1354,14 +1004,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz",
- "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+ "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-simple-access": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1371,15 +1021,16 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz",
- "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+ "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1389,13 +1040,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz",
- "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+ "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1405,13 +1057,14 @@
}
},
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
- "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1421,12 +1074,13 @@
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz",
- "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+ "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1436,13 +1090,13 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz",
- "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==",
+ "version": "7.26.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
+ "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1452,13 +1106,13 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz",
- "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+ "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1468,16 +1122,15 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz",
- "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+ "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.23.3",
- "@babel/helper-compilation-targets": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.23.3"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1487,13 +1140,14 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz",
- "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+ "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.20"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1503,13 +1157,13 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz",
- "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+ "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1519,14 +1173,14 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz",
- "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1536,12 +1190,13 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz",
- "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+ "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1551,13 +1206,14 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz",
- "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+ "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1567,15 +1223,15 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz",
- "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+ "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1585,12 +1241,13 @@
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz",
- "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+ "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1600,12 +1257,13 @@
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz",
- "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz",
+ "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.26.5",
"regenerator-transform": "^0.15.2"
},
"engines": {
@@ -1615,13 +1273,31 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+ "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz",
- "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+ "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1631,12 +1307,13 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz",
- "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+ "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1646,13 +1323,14 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz",
- "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+ "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1662,12 +1340,13 @@
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz",
- "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+ "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1677,12 +1356,13 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz",
- "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz",
+ "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1692,12 +1372,13 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz",
- "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz",
+ "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1707,12 +1388,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz",
- "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+ "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1722,13 +1404,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz",
- "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+ "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1738,13 +1421,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz",
- "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+ "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1754,13 +1438,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz",
- "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+ "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.15",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1770,90 +1455,80 @@
}
},
"node_modules/@babel/preset-env": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz",
- "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==",
- "dev": true,
- "dependencies": {
- "@babel/compat-data": "^7.23.5",
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-option": "^7.23.5",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3",
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3",
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz",
+ "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.23.3",
- "@babel/plugin-syntax-import-attributes": "^7.23.3",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.23.3",
- "@babel/plugin-transform-async-generator-functions": "^7.23.4",
- "@babel/plugin-transform-async-to-generator": "^7.23.3",
- "@babel/plugin-transform-block-scoped-functions": "^7.23.3",
- "@babel/plugin-transform-block-scoping": "^7.23.4",
- "@babel/plugin-transform-class-properties": "^7.23.3",
- "@babel/plugin-transform-class-static-block": "^7.23.4",
- "@babel/plugin-transform-classes": "^7.23.5",
- "@babel/plugin-transform-computed-properties": "^7.23.3",
- "@babel/plugin-transform-destructuring": "^7.23.3",
- "@babel/plugin-transform-dotall-regex": "^7.23.3",
- "@babel/plugin-transform-duplicate-keys": "^7.23.3",
- "@babel/plugin-transform-dynamic-import": "^7.23.4",
- "@babel/plugin-transform-exponentiation-operator": "^7.23.3",
- "@babel/plugin-transform-export-namespace-from": "^7.23.4",
- "@babel/plugin-transform-for-of": "^7.23.6",
- "@babel/plugin-transform-function-name": "^7.23.3",
- "@babel/plugin-transform-json-strings": "^7.23.4",
- "@babel/plugin-transform-literals": "^7.23.3",
- "@babel/plugin-transform-logical-assignment-operators": "^7.23.4",
- "@babel/plugin-transform-member-expression-literals": "^7.23.3",
- "@babel/plugin-transform-modules-amd": "^7.23.3",
- "@babel/plugin-transform-modules-commonjs": "^7.23.3",
- "@babel/plugin-transform-modules-systemjs": "^7.23.3",
- "@babel/plugin-transform-modules-umd": "^7.23.3",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
- "@babel/plugin-transform-new-target": "^7.23.3",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4",
- "@babel/plugin-transform-numeric-separator": "^7.23.4",
- "@babel/plugin-transform-object-rest-spread": "^7.23.4",
- "@babel/plugin-transform-object-super": "^7.23.3",
- "@babel/plugin-transform-optional-catch-binding": "^7.23.4",
- "@babel/plugin-transform-optional-chaining": "^7.23.4",
- "@babel/plugin-transform-parameters": "^7.23.3",
- "@babel/plugin-transform-private-methods": "^7.23.3",
- "@babel/plugin-transform-private-property-in-object": "^7.23.4",
- "@babel/plugin-transform-property-literals": "^7.23.3",
- "@babel/plugin-transform-regenerator": "^7.23.3",
- "@babel/plugin-transform-reserved-words": "^7.23.3",
- "@babel/plugin-transform-shorthand-properties": "^7.23.3",
- "@babel/plugin-transform-spread": "^7.23.3",
- "@babel/plugin-transform-sticky-regex": "^7.23.3",
- "@babel/plugin-transform-template-literals": "^7.23.3",
- "@babel/plugin-transform-typeof-symbol": "^7.23.3",
- "@babel/plugin-transform-unicode-escapes": "^7.23.3",
- "@babel/plugin-transform-unicode-property-regex": "^7.23.3",
- "@babel/plugin-transform-unicode-regex": "^7.23.3",
- "@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
+ "@babel/plugin-transform-arrow-functions": "^7.25.9",
+ "@babel/plugin-transform-async-generator-functions": "^7.26.8",
+ "@babel/plugin-transform-async-to-generator": "^7.25.9",
+ "@babel/plugin-transform-block-scoped-functions": "^7.26.5",
+ "@babel/plugin-transform-block-scoping": "^7.25.9",
+ "@babel/plugin-transform-class-properties": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
+ "@babel/plugin-transform-classes": "^7.25.9",
+ "@babel/plugin-transform-computed-properties": "^7.25.9",
+ "@babel/plugin-transform-destructuring": "^7.25.9",
+ "@babel/plugin-transform-dotall-regex": "^7.25.9",
+ "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-dynamic-import": "^7.25.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.26.3",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-for-of": "^7.26.9",
+ "@babel/plugin-transform-function-name": "^7.25.9",
+ "@babel/plugin-transform-json-strings": "^7.25.9",
+ "@babel/plugin-transform-literals": "^7.25.9",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+ "@babel/plugin-transform-modules-amd": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.26.3",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+ "@babel/plugin-transform-modules-umd": "^7.25.9",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-new-target": "^7.25.9",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
+ "@babel/plugin-transform-numeric-separator": "^7.25.9",
+ "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+ "@babel/plugin-transform-object-super": "^7.25.9",
+ "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9",
+ "@babel/plugin-transform-private-methods": "^7.25.9",
+ "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+ "@babel/plugin-transform-property-literals": "^7.25.9",
+ "@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+ "@babel/plugin-transform-reserved-words": "^7.25.9",
+ "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+ "@babel/plugin-transform-spread": "^7.25.9",
+ "@babel/plugin-transform-sticky-regex": "^7.25.9",
+ "@babel/plugin-transform-template-literals": "^7.26.8",
+ "@babel/plugin-transform-typeof-symbol": "^7.26.7",
+ "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+ "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
"@babel/preset-modules": "0.1.6-no-external-plugins",
- "babel-plugin-polyfill-corejs2": "^0.4.6",
- "babel-plugin-polyfill-corejs3": "^0.8.5",
- "babel-plugin-polyfill-regenerator": "^0.5.3",
- "core-js-compat": "^3.31.0",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.40.0",
"semver": "^6.3.1"
},
"engines": {
@@ -1868,6 +1543,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
@@ -1877,6 +1553,7 @@
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/types": "^7.4.4",
@@ -1886,17 +1563,12 @@
"@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
- "dev": true
- },
"node_modules/@babel/runtime": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
- "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
+ "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1904,34 +1576,40 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/runtime/node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+ "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
+ "@babel/code-frame": "^7.26.2",
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz",
- "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.6",
- "@babel/types": "^7.23.6",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
+ "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.27.0",
+ "@babel/parser": "^7.27.0",
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1944,19 +1622,19 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/types": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
- "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
- "dev": true,
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+ "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.23.4",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1966,7 +1644,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.0.0.tgz",
"integrity": "sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
@@ -1976,6 +1655,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -1992,6 +1672,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -2008,6 +1689,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -2024,6 +1706,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -2040,6 +1723,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -2056,6 +1740,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -2072,6 +1757,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -2088,6 +1774,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2104,6 +1791,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2120,6 +1808,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2136,6 +1825,7 @@
"loong64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2152,6 +1842,7 @@
"mips64el"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2168,6 +1859,7 @@
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2184,6 +1876,7 @@
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2200,6 +1893,7 @@
"s390x"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2216,6 +1910,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2232,6 +1927,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"netbsd"
@@ -2248,6 +1944,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
@@ -2264,6 +1961,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"sunos"
@@ -2280,6 +1978,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -2296,6 +1995,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -2312,6 +2012,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -2321,25 +2022,30 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
+ "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "eslint-visitor-keys": "^3.3.0"
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.10.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
- "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
@@ -2349,6 +2055,7 @@
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@@ -2368,22 +2075,25 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
- "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.13",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
- "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.1",
- "debug": "^4.1.1",
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
@@ -2395,6 +2105,7 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=12.22"
},
@@ -2404,78 +2115,88 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
- "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
- "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@kurkle/color": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
- "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
+ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
+ "license": "MIT"
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -2489,6 +2210,7 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 8"
}
@@ -2498,6 +2220,7 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
@@ -2506,56 +2229,208 @@
"node": ">= 8"
}
},
- "node_modules/@rushstack/eslint-patch": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz",
- "integrity": "sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw==",
- "dev": true
- },
- "node_modules/@surma/rollup-plugin-off-main-thread": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
- "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
- "dev": true,
+ "node_modules/@primeuix/styled": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.5.1.tgz",
+ "integrity": "sha512-5Ftw/KSauDPClQ8F2qCyCUF7cIUEY4yLNikf0rKV7Vsb8zGYNK0dahQe7CChaR6M2Kn+NA2DSBSk76ZXqj6Uog==",
+ "license": "MIT",
"dependencies": {
- "ejs": "^3.1.6",
- "json5": "^2.2.0",
- "magic-string": "^0.25.0",
- "string.prototype.matchall": "^4.0.6"
- }
- },
- "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "bin": {
- "json5": "lib/cli.js"
+ "@primeuix/utils": "^0.5.3"
},
"engines": {
- "node": ">=6"
+ "node": ">=12.11.0"
}
},
- "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": {
- "version": "0.25.9",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
- "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
- "dev": true,
+ "node_modules/@primeuix/styles": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@primeuix/styles/-/styles-1.0.1.tgz",
+ "integrity": "sha512-R7SX001ILHIJM9hh1opbsuOFFK8dOM8GY1y99jaCFnAc5gGy3mFPJMhoexRYV1a6UZ2YbfcsQVPbIhoONI1gfg==",
+ "license": "MIT",
"dependencies": {
- "sourcemap-codec": "^1.4.8"
+ "@primeuix/styled": "^0.5.1"
}
},
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
- },
+ "node_modules/@primeuix/themes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@primeuix/themes/-/themes-1.0.1.tgz",
+ "integrity": "sha512-RllttI3oGTZa66UQDCIA2lPnJvO/xqtNpy+0eNql6fIxdS2AUg5n7L81jTZrHNZ+31T5OBzL/SGFCDycmHTz2g==",
+ "license": "MIT",
+ "dependencies": {
+ "@primeuix/styled": "^0.5.1"
+ }
+ },
+ "node_modules/@primeuix/utils": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.5.3.tgz",
+ "integrity": "sha512-7SGh7734wcF1/uK6RzO6Z6CBjGQ97GDHfpyl2F1G/c7R0z9hkT/V72ypDo82AWcCS7Ta07oIjDpOCTkSVZuEGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.11.0"
+ }
+ },
+ "node_modules/@primevue/core": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.3.3.tgz",
+ "integrity": "sha512-kSkN5oourG7eueoFPIqiNX3oDT/f0I5IRK3uOY/ytz+VzTZp5yuaCN0Nt42ZQpVXjDxMxDvUhIdaXVrjr58NhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@primeuix/styled": "^0.5.0",
+ "@primeuix/utils": "^0.5.1"
+ },
+ "engines": {
+ "node": ">=12.11.0"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
+ "node_modules/@primevue/icons": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.3.3.tgz",
+ "integrity": "sha512-ouQaxHyeFB6MSfEGGbjaK5Qv9efS1xZGetZoU5jcPm090MSYLFtroP1CuK3lZZAQals06TZ6T6qcoNukSHpK5w==",
+ "license": "MIT",
+ "dependencies": {
+ "@primeuix/utils": "^0.5.1",
+ "@primevue/core": "4.3.3"
+ },
+ "engines": {
+ "node": ">=12.11.0"
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
+ "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-terser": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
+ "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "serialize-javascript": "^6.0.1",
+ "smob": "^1.0.0",
+ "terser": "^5.17.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
+ "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.11.0.tgz",
+ "integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@surma/rollup-plugin-off-main-thread": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
+ "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "ejs": "^3.1.6",
+ "json5": "^2.2.0",
+ "magic-string": "^0.25.0",
+ "string.prototype.matchall": "^4.0.6"
+ }
+ },
+ "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
- "version": "18.19.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz",
- "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==",
+ "version": "18.19.86",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.86.tgz",
+ "integrity": "sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -2563,34 +2438,36 @@
"node_modules/@types/pako": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.3.tgz",
- "integrity": "sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q=="
+ "integrity": "sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q==",
+ "license": "MIT"
},
"node_modules/@types/resolve": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
- "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
"dev": true,
- "dependencies": {
- "@types/node": "*"
- }
+ "license": "MIT"
},
"node_modules/@types/semver": {
- "version": "7.5.6",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
- "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
- "dev": true
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
+ "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
"integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.62.0",
@@ -2625,6 +2502,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/scope-manager": "5.62.0",
"@typescript-eslint/types": "5.62.0",
@@ -2652,6 +2530,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
"integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/types": "5.62.0",
"@typescript-eslint/visitor-keys": "5.62.0"
@@ -2669,6 +2548,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
"integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/typescript-estree": "5.62.0",
"@typescript-eslint/utils": "5.62.0",
@@ -2696,6 +2576,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
"integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -2709,6 +2590,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
"integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/types": "5.62.0",
"@typescript-eslint/visitor-keys": "5.62.0",
@@ -2736,6 +2618,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
"integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
@@ -2762,6 +2645,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
"integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/types": "5.62.0",
"eslint-visitor-keys": "^3.3.0"
@@ -2775,16 +2659,18 @@
}
},
"node_modules/@ungap/structured-clone": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
- "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
- "dev": true
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/@vite-pwa/assets-generator": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-0.2.1.tgz",
- "integrity": "sha512-NoFsE/XzmkF3WDr+1NjbjdP4GDBZMPQ49eFS33H8FlIH50g4AAK5+W3Y2xeRy7tKE5nB7MLYybesSqk+zD4L0Q==",
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@vite-pwa/assets-generator/-/assets-generator-0.2.6.tgz",
+ "integrity": "sha512-kK44dXltvoubEo5B+6tCGjUrOWOE1+dA4DForbFpO1rKy2wSkAVGrs8tyfN6DzTig89/QKyV8XYodgmaKyrYng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cac": "^6.7.14",
"colorette": "^2.0.20",
@@ -2804,10 +2690,11 @@
}
},
"node_modules/@vitejs/plugin-vue": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.2.tgz",
- "integrity": "sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==",
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
+ "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
@@ -2821,6 +2708,7 @@
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz",
"integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@volar/source-map": "1.11.1"
}
@@ -2830,6 +2718,7 @@
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz",
"integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"muggle-string": "^0.3.1"
}
@@ -2839,67 +2728,74 @@
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz",
"integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@volar/language-core": "1.11.1",
"path-browserify": "^1.0.1"
}
},
"node_modules/@vue/compiler-core": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.11.tgz",
- "integrity": "sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==",
- "dependencies": {
- "@babel/parser": "^7.23.5",
- "@vue/shared": "3.3.11",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
+ "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/shared": "3.5.13",
+ "entities": "^4.5.0",
"estree-walker": "^2.0.2",
- "source-map-js": "^1.0.2"
+ "source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.11.tgz",
- "integrity": "sha512-zoAiUIqSKqAJ81WhfPXYmFGwDRuO+loqLxvXmfUdR5fOitPoUiIeFI9cTTyv9MU5O1+ZZglJVTusWzy+wfk5hw==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
+ "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
+ "license": "MIT",
"dependencies": {
- "@vue/compiler-core": "3.3.11",
- "@vue/shared": "3.3.11"
+ "@vue/compiler-core": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.11.tgz",
- "integrity": "sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==",
- "dependencies": {
- "@babel/parser": "^7.23.5",
- "@vue/compiler-core": "3.3.11",
- "@vue/compiler-dom": "3.3.11",
- "@vue/compiler-ssr": "3.3.11",
- "@vue/reactivity-transform": "3.3.11",
- "@vue/shared": "3.3.11",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
+ "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/compiler-core": "3.5.13",
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13",
"estree-walker": "^2.0.2",
- "magic-string": "^0.30.5",
- "postcss": "^8.4.32",
- "source-map-js": "^1.0.2"
+ "magic-string": "^0.30.11",
+ "postcss": "^8.4.48",
+ "source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.11.tgz",
- "integrity": "sha512-Zd66ZwMvndxRTgVPdo+muV4Rv9n9DwQ4SSgWWKWkPFebHQfVYRrVjeygmmDmPewsHyznCNvJ2P2d6iOOhdv8Qg==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
+ "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
+ "license": "MIT",
"dependencies": {
- "@vue/compiler-dom": "3.3.11",
- "@vue/shared": "3.3.11"
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/devtools-api": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz",
- "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+ "license": "MIT"
},
"node_modules/@vue/eslint-config-prettier": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz",
"integrity": "sha512-Pv/lVr0bAzSIHLd9iz0KnvAr4GKyCEl+h52bc4e5yWuDVtLgFwycF7nrbWTAQAS+FU6q1geVd07lc6EWfJiWKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0"
@@ -2914,6 +2810,7 @@
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-11.0.3.tgz",
"integrity": "sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
@@ -2934,10 +2831,11 @@
}
},
"node_modules/@vue/language-core": {
- "version": "1.8.25",
- "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.25.tgz",
- "integrity": "sha512-NJk/5DnAZlpvXX8BdWmHI45bWGLViUaS3R/RMrmFSvFMSbJKuEODpM4kR0F0Ofv5SFzCWuNiMhxameWpVdQsnA==",
+ "version": "1.8.27",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz",
+ "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@volar/language-core": "~1.11.1",
"@volar/source-map": "~1.11.1",
@@ -2963,15 +2861,17 @@
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/@vue/language-core/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -2983,66 +2883,61 @@
}
},
"node_modules/@vue/reactivity": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.11.tgz",
- "integrity": "sha512-D5tcw091f0nuu+hXq5XANofD0OXnBmaRqMYl5B3fCR+mX+cXJIGNw/VNawBqkjLNWETrFW0i+xH9NvDbTPVh7g==",
- "dependencies": {
- "@vue/shared": "3.3.11"
- }
- },
- "node_modules/@vue/reactivity-transform": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.11.tgz",
- "integrity": "sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
+ "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
+ "license": "MIT",
"dependencies": {
- "@babel/parser": "^7.23.5",
- "@vue/compiler-core": "3.3.11",
- "@vue/shared": "3.3.11",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.30.5"
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.11.tgz",
- "integrity": "sha512-g9ztHGwEbS5RyWaOpXuyIVFTschclnwhqEbdy5AwGhYOgc7m/q3NFwr50MirZwTTzX55JY8pSkeib9BX04NIpw==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
+ "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
+ "license": "MIT",
"dependencies": {
- "@vue/reactivity": "3.3.11",
- "@vue/shared": "3.3.11"
+ "@vue/reactivity": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.11.tgz",
- "integrity": "sha512-OlhtV1PVpbgk+I2zl+Y5rQtDNcCDs12rsRg71XwaA2/Rbllw6mBLMi57VOn8G0AjOJ4Mdb4k56V37+g8ukShpQ==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
+ "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
+ "license": "MIT",
"dependencies": {
- "@vue/runtime-core": "3.3.11",
- "@vue/shared": "3.3.11",
- "csstype": "^3.1.2"
+ "@vue/reactivity": "3.5.13",
+ "@vue/runtime-core": "3.5.13",
+ "@vue/shared": "3.5.13",
+ "csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.11.tgz",
- "integrity": "sha512-AIWk0VwwxCAm4wqtJyxBylRTXSy1wCLOKbWxHaHiu14wjsNYtiRCSgVuqEPVuDpErOlRdNnuRgipQfXRLjLN5A==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
+ "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
+ "license": "MIT",
"dependencies": {
- "@vue/compiler-ssr": "3.3.11",
- "@vue/shared": "3.3.11"
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13"
},
"peerDependencies": {
- "vue": "3.3.11"
+ "vue": "3.5.13"
}
},
"node_modules/@vue/shared": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.11.tgz",
- "integrity": "sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw=="
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
+ "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
+ "license": "MIT"
},
"node_modules/@vue/tsconfig": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.1.3.tgz",
"integrity": "sha512-kQVsh8yyWPvHpb8gIc9l/HIDiiVUy1amynLNpCy8p+FoCiZXCo6fQos5/097MmnNZc9AtseDsCrfkhqCrJ8Olg==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"@types/node": "*"
},
@@ -3053,10 +2948,11 @@
}
},
"node_modules/acorn": {
- "version": "8.11.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
- "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -3069,6 +2965,7 @@
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
@@ -3078,6 +2975,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -3094,6 +2992,7 @@
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3103,6 +3002,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -3117,16 +3017,21 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "dev": true,
+ "license": "Python-2.0"
},
"node_modules/array-buffer-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
- "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "is-array-buffer": "^3.0.1"
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3137,23 +3042,25 @@
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz",
- "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
- "is-array-buffer": "^3.0.2",
- "is-shared-array-buffer": "^1.0.2"
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -3162,25 +3069,48 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -3189,29 +3119,32 @@
}
},
"node_modules/axios": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
- "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
+ "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
+ "license": "MIT",
"dependencies": {
- "follow-redirects": "^1.15.0",
+ "follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/b4a": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
- "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==",
- "dev": true
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
+ "dev": true,
+ "license": "Apache-2.0"
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.7",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz",
- "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==",
+ "version": "0.4.13",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz",
+ "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.4.4",
+ "@babel/helper-define-polyfill-provider": "^0.6.4",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -3223,30 +3156,33 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.8.7",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz",
- "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==",
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.4",
- "core-js-compat": "^3.33.1"
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz",
- "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz",
+ "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.4"
+ "@babel/helper-define-polyfill-provider": "^0.6.4"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -3256,21 +3192,95 @@
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+ "license": "MIT",
"dependencies": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
- "node_modules/babel-runtime/node_modules/regenerator-runtime": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
- "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
- },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bare-events": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/bare-fs": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.2.tgz",
+ "integrity": "sha512-8wSeOia5B7LwD4+h465y73KOdj5QHsbbuoUfPBi+pXgFJIPuG7SsiOdJuijWMyfid49eD+WivpfY7KT8gbAzBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-events": "^2.5.4",
+ "bare-path": "^3.0.0",
+ "bare-stream": "^2.6.4"
+ },
+ "engines": {
+ "bare": ">=1.16.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/bare-os": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
+ "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "bare": ">=1.14.0"
+ }
+ },
+ "node_modules/bare-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
+ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-os": "^3.0.1"
+ }
+ },
+ "node_modules/bare-stream": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
+ "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "streamx": "^2.21.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*",
+ "bare-events": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ },
+ "bare-events": {
+ "optional": true
+ }
+ }
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -3290,13 +3300,15 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@ -3307,34 +3319,37 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/browserslist": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
- "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
"dev": true,
"funding": [
{
@@ -3350,11 +3365,12 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001565",
- "electron-to-chromium": "^1.4.601",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
@@ -3382,6 +3398,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@@ -3391,38 +3408,63 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
- },
- "node_modules/builtin-modules": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
- "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
"dev": true,
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
+ "license": "MIT"
},
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/call-bind": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
- "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.1",
- "set-function-length": "^1.1.1"
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3433,14 +3475,15 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001570",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz",
- "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==",
+ "version": "1.0.30001710",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001710.tgz",
+ "integrity": "sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA==",
"dev": true,
"funding": [
{
@@ -3455,13 +3498,15 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -3474,27 +3519,30 @@
}
},
"node_modules/chart.js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
- "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
+ "version": "4.4.8",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz",
+ "integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==",
+ "license": "MIT",
"dependencies": {
"@kurkle/color": "^0.3.0"
},
"engines": {
- "pnpm": ">=7"
+ "pnpm": ">=8"
}
},
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
@@ -3508,6 +3556,7 @@
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
@@ -3519,13 +3568,15 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
@@ -3535,12 +3586,14 @@
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -3548,11 +3601,19 @@
"node": ">= 0.8"
}
},
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/common-tags": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
"integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -3561,19 +3622,22 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz",
"integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/consola": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz",
- "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.10.0"
}
@@ -3582,22 +3646,25 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
- "hasInstallScript": true
+ "hasInstallScript": true,
+ "license": "MIT"
},
"node_modules/core-js-compat": {
- "version": "3.34.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz",
- "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==",
+ "version": "3.41.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz",
+ "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "browserslist": "^4.22.2"
+ "browserslist": "^4.24.4"
},
"funding": {
"type": "opencollective",
@@ -3605,10 +3672,11 @@
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -3623,6 +3691,7 @@
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3632,6 +3701,7 @@
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
+ "license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
},
@@ -3642,29 +3712,86 @@
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
},
- "node_modules/de-indent": {
+ "node_modules/data-view-buffer": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
- "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
- "dev": true
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
},
"engines": {
- "node": ">=6.0"
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
}
},
"node_modules/decode-bmp": {
@@ -3672,6 +3799,7 @@
"resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz",
"integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@canvas/image-data": "^1.0.0",
"to-data-view": "^1.1.0"
@@ -3685,6 +3813,7 @@
"resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz",
"integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@canvas/image-data": "^1.0.0",
"decode-bmp": "^0.2.0",
@@ -3699,6 +3828,7 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
@@ -3714,6 +3844,7 @@
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -3722,20 +3853,35 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/define-data-property": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
- "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.2.1",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.0"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
@@ -3743,6 +3889,7 @@
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
@@ -3756,24 +3903,27 @@
}
},
"node_modules/defu": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.3.tgz",
- "integrity": "sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==",
- "dev": true
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/detect-libc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=8"
}
@@ -3783,6 +3933,7 @@
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-type": "^4.0.0"
},
@@ -3795,6 +3946,7 @@
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"esutils": "^2.0.2"
},
@@ -3802,11 +3954,26 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/ejs": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
- "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"jake": "^10.8.5"
},
@@ -3818,74 +3985,102 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.614",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz",
- "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==",
- "dev": true
+ "version": "1.5.132",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.132.tgz",
+ "integrity": "sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
"node_modules/es-abstract": {
- "version": "1.22.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
- "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==",
- "dev": true,
- "dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "arraybuffer.prototype.slice": "^1.0.2",
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.5",
- "es-set-tostringtag": "^2.0.1",
- "es-to-primitive": "^1.2.1",
- "function.prototype.name": "^1.1.6",
- "get-intrinsic": "^1.2.2",
- "get-symbol-description": "^1.0.0",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0",
- "internal-slot": "^1.0.5",
- "is-array-buffer": "^3.0.2",
+ "version": "1.23.9",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
+ "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.0",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
"is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.12",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.13.1",
+ "is-data-view": "^1.0.2",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.3",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "safe-array-concat": "^1.0.1",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trim": "^1.2.8",
- "string.prototype.trimend": "^1.0.7",
- "string.prototype.trimstart": "^1.0.7",
- "typed-array-buffer": "^1.0.0",
- "typed-array-byte-length": "^1.0.0",
- "typed-array-byte-offset": "^1.0.0",
- "typed-array-length": "^1.0.4",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.13"
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.18"
},
"engines": {
"node": ">= 0.4"
@@ -3894,29 +4089,61 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-set-tostringtag": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
- "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==",
- "dev": true,
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.2.2",
- "has-tostringtag": "^1.0.0",
- "hasown": "^2.0.0"
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -3931,6 +4158,7 @@
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@@ -3963,10 +4191,11 @@
}
},
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -3976,6 +4205,7 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -3984,16 +4214,18 @@
}
},
"node_modules/eslint": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz",
- "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.55.0",
- "@humanwhocodes/config-array": "^0.11.13",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -4043,6 +4275,7 @@
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
"integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
"dev": true,
+ "license": "MIT",
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -4055,6 +4288,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
"integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prettier-linter-helpers": "^1.0.0"
},
@@ -4072,24 +4306,26 @@
}
},
"node_modules/eslint-plugin-vue": {
- "version": "9.19.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz",
- "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==",
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz",
+ "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
+ "globals": "^13.24.0",
"natural-compare": "^1.4.0",
"nth-check": "^2.1.1",
- "postcss-selector-parser": "^6.0.13",
- "semver": "^7.5.4",
- "vue-eslint-parser": "^9.3.1",
+ "postcss-selector-parser": "^6.0.15",
+ "semver": "^7.6.3",
+ "vue-eslint-parser": "^9.4.3",
"xml-name-validator": "^4.0.0"
},
"engines": {
"node": "^14.17.0 || >=16.0.0"
},
"peerDependencies": {
- "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/eslint-scope": {
@@ -4097,6 +4333,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -4110,6 +4347,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -4122,6 +4360,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
@@ -4138,6 +4377,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -4147,6 +4387,7 @@
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.9.0",
"acorn-jsx": "^5.3.2",
@@ -4160,10 +4401,11 @@
}
},
"node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"estraverse": "^5.1.0"
},
@@ -4176,6 +4418,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -4185,6 +4428,7 @@
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -4197,6 +4441,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -4206,6 +4451,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
@@ -4213,13 +4459,15 @@
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -4229,6 +4477,7 @@
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"dev": true,
+ "license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
}
@@ -4237,31 +4486,35 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
- "dev": true
+ "dev": true,
+ "license": "Apache-2.0"
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
- "micromatch": "^4.0.4"
+ "micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
@@ -4272,6 +4525,7 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -4283,19 +4537,39 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
},
"node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
}
@@ -4305,6 +4579,7 @@
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"flat-cache": "^3.0.4"
},
@@ -4317,6 +4592,7 @@
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.0.1"
}
@@ -4326,6 +4602,7 @@
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -4335,6 +4612,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -4343,10 +4621,11 @@
}
},
"node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -4359,6 +4638,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
@@ -4375,6 +4655,7 @@
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.3",
@@ -4385,21 +4666,23 @@
}
},
"node_modules/flatted": {
- "version": "3.2.9",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
- "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
- "dev": true
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/follow-redirects": {
- "version": "1.15.5",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
- "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
+ "license": "MIT",
"engines": {
"node": ">=4.0"
},
@@ -4410,21 +4693,30 @@
}
},
"node_modules/for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-callable": "^1.1.3"
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
+ "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
+ "license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
"mime-types": "^2.1.12"
},
"engines": {
@@ -4435,13 +4727,15 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
@@ -4456,7 +4750,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
@@ -4464,6 +4759,7 @@
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -4476,21 +4772,24 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/function.prototype.name": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
- "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "functions-have-names": "^1.2.3"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
@@ -4504,6 +4803,7 @@
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true,
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -4513,20 +4813,30 @@
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
- "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
- "dev": true,
- "dependencies": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0"
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4536,16 +4846,32 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
"integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
"node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
@@ -4558,13 +4884,16 @@
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
+ "license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -4585,6 +4914,7 @@
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
},
@@ -4597,6 +4927,7 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -4608,12 +4939,14 @@
}
},
"node_modules/globalthis": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
- "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "define-properties": "^1.1.3"
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -4627,6 +4960,7 @@
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -4643,12 +4977,12 @@
}
},
"node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
- "dev": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3"
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4658,19 +4992,25 @@
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -4680,27 +5020,33 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
- "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.2.2"
+ "es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -4709,10 +5055,10 @@
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "dev": true,
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -4721,12 +5067,12 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "dev": true,
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -4736,10 +5082,10 @@
}
},
"node_modules/hasown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
- "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
- "dev": true,
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -4752,6 +5098,7 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
+ "license": "MIT",
"bin": {
"he": "bin/he"
}
@@ -4760,19 +5107,22 @@
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/ico-endec": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ico-endec/-/ico-endec-0.1.6.tgz",
"integrity": "sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==",
- "dev": true
+ "dev": true,
+ "license": "MPL-2.0"
},
"node_modules/idb": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
"integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/ieee754": {
"version": "1.2.1",
@@ -4792,22 +5142,25 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "BSD-3-Clause"
},
"node_modules/ignore": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
- "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -4824,6 +5177,7 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.8.19"
}
@@ -4832,7 +5186,9 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
+ "license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -4842,37 +5198,44 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/internal-slot": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
- "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.2.2",
- "hasown": "^2.0.0",
- "side-channel": "^1.0.4"
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-array-buffer": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
- "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.0",
- "is-typed-array": "^1.1.10"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4882,28 +5245,54 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-bigints": "^1.0.1"
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -4917,6 +5306,7 @@
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -4925,24 +5315,48 @@
}
},
"node_modules/is-core-module": {
- "version": "2.13.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
- "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "hasown": "^2.0.0"
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -4956,33 +5370,20 @@
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
+ "call-bound": "^1.0.3"
},
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
- "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
- "dev": true
- },
- "node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -4990,22 +5391,77 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -5019,6 +5475,7 @@
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -5028,18 +5485,22 @@
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -5053,29 +5514,62 @@
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
"integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-shared-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -5085,12 +5579,15 @@
}
},
"node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -5100,13 +5597,27 @@
}
},
"node_modules/is-typed-array": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
- "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "which-typed-array": "^1.1.11"
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -5115,12 +5626,33 @@
}
},
"node_modules/is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -5130,19 +5662,22 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/jake": {
- "version": "10.8.7",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz",
- "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==",
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"async": "^3.2.3",
"chalk": "^4.0.2",
@@ -5156,17 +5691,12 @@
"node": ">=10"
}
},
- "node_modules/jake/node_modules/async": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
- "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
- "dev": true
- },
"node_modules/jiti": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
- "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
+ "license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
}
@@ -5174,19 +5704,22 @@
"node_modules/js-sha256": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz",
- "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q=="
+ "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==",
+ "license": "MIT"
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@@ -5195,58 +5728,72 @@
}
},
"node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
- "node": ">=4"
+ "node": ">=6"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
- "dev": true
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/jsonc-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
- "dev": true
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
@@ -5259,6 +5806,7 @@
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
"integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -5268,6 +5816,7 @@
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
}
@@ -5277,6 +5826,7 @@
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -5286,6 +5836,7 @@
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
@@ -5299,6 +5850,7 @@
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
"integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.1.2",
"parse-json": "^4.0.0",
@@ -5314,6 +5866,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-locate": "^5.0.0"
},
@@ -5328,47 +5881,56 @@
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
+ "yallist": "^3.0.2"
}
},
"node_modules/magic-string": {
- "version": "0.30.5",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
- "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- },
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">= 0.4"
}
},
"node_modules/memorystream": {
@@ -5380,28 +5942,24 @@
"node": ">= 0.10.0"
}
},
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
- },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@@ -5412,6 +5970,7 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -5420,6 +5979,7 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -5432,6 +5992,7 @@
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -5444,6 +6005,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -5456,6 +6018,7 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -5464,42 +6027,34 @@
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "dev": true
- },
- "node_modules/mlly": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz",
- "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==",
"dev": true,
- "dependencies": {
- "acorn": "^8.10.0",
- "pathe": "^1.1.1",
- "pkg-types": "^1.0.3",
- "ufo": "^1.3.0"
- }
+ "license": "MIT"
},
"node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/muggle-string": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz",
"integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -5508,34 +6063,39 @@
}
},
"node_modules/napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
- "dev": true
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+ "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/natural-compare-lite": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/node-abi": {
- "version": "3.52.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz",
- "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==",
+ "version": "3.74.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
+ "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"semver": "^7.3.5"
},
@@ -5547,19 +6107,22 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
- "dev": true
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
@@ -5572,6 +6135,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver"
}
@@ -5581,6 +6145,7 @@
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
"integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
"chalk": "^2.4.1",
@@ -5606,6 +6171,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-convert": "^1.9.0"
},
@@ -5618,6 +6184,7 @@
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -5632,6 +6199,7 @@
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"color-name": "1.1.3"
}
@@ -5640,13 +6208,15 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/npm-run-all/node_modules/cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
@@ -5663,6 +6233,7 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.8.0"
}
@@ -5672,6 +6243,7 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -5681,6 +6253,7 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -5690,6 +6263,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver"
}
@@ -5699,6 +6273,7 @@
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"shebang-regex": "^1.0.0"
},
@@ -5711,6 +6286,7 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -5720,6 +6296,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
},
@@ -5732,6 +6309,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -5744,6 +6322,7 @@
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0"
},
@@ -5752,10 +6331,14 @@
}
},
"node_modules/object-inspect": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
- "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -5765,19 +6348,23 @@
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.assign": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
- "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
- "has-symbols": "^1.0.3",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
"object-keys": "^1.1.1"
},
"engines": {
@@ -5792,32 +6379,53 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/optionator": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
- "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@aashutoshrathi/word-wrap": "^1.2.3",
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
- "type-check": "^0.4.0"
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
},
@@ -5833,6 +6441,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-limit": "^3.0.2"
},
@@ -5846,13 +6455,15 @@
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
- "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
+ "license": "(MIT AND Zlib)"
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
},
@@ -5865,6 +6476,7 @@
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"error-ex": "^1.3.1",
"json-parse-better-errors": "^1.0.1"
@@ -5877,13 +6489,15 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -5893,6 +6507,7 @@
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -5902,6 +6517,7 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -5910,33 +6526,31 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
- "node_modules/pathe": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
- "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==",
- "dev": true
- },
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8.6"
},
@@ -5949,6 +6563,7 @@
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
"integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
"dev": true,
+ "license": "MIT",
"bin": {
"pidtree": "bin/pidtree.js"
},
@@ -5961,25 +6576,25 @@
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
- "node_modules/pkg-types": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz",
- "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==",
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
"dev": true,
- "dependencies": {
- "jsonc-parser": "^3.2.0",
- "mlly": "^1.2.0",
- "pathe": "^1.1.0"
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"funding": [
{
"type": "opencollective",
@@ -5994,20 +6609,22 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
- "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -6017,17 +6634,18 @@
}
},
"node_modules/prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+ "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
+ "napi-build-utils": "^2.0.0",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
@@ -6043,10 +6661,11 @@
}
},
"node_modules/prebuild-install/node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
+ "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
@@ -6059,6 +6678,7 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@@ -6075,6 +6695,7 @@
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8.0"
}
@@ -6084,6 +6705,7 @@
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
+ "license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
},
@@ -6099,6 +6721,7 @@
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-diff": "^1.1.2"
},
@@ -6106,29 +6729,53 @@
"node": ">=6.0.0"
}
},
+ "node_modules/pretty-bytes": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
+ "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/primeicons": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz",
- "integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA=="
+ "integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA==",
+ "license": "MIT"
},
"node_modules/primevue": {
- "version": "3.49.0",
- "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.49.0.tgz",
- "integrity": "sha512-1lFTU/WK1wcjaaKqce7XldrH4MGPySXxH9Nyoj0d9QiGehePw9JUQrGhVgfjx3I/MD/VgE85wF1HihqtPJehbw==",
- "peerDependencies": {
- "vue": "^3.0.0"
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.3.3.tgz",
+ "integrity": "sha512-nooYVoEz5CdP3EhUkD6c3qTdRmpLHZh75fBynkUkl46K8y5rksHTjdSISiDijwTA5STQIOkyqLb+RM+HQ6nC1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@primeuix/styled": "^0.5.0",
+ "@primeuix/styles": "^1.0.0",
+ "@primeuix/utils": "^0.5.1",
+ "@primevue/core": "4.3.3",
+ "@primevue/icons": "4.3.3"
+ },
+ "engines": {
+ "node": ">=12.11.0"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
},
"node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -6139,6 +6786,7 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -6161,19 +6809,15 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
- },
- "node_modules/queue-tick": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
- "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
- "dev": true
+ ],
+ "license": "MIT"
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -6183,6 +6827,7 @@
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true,
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@@ -6198,6 +6843,7 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -6207,6 +6853,7 @@
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
"integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"load-json-file": "^4.0.0",
"normalize-package-data": "^2.3.2",
@@ -6221,6 +6868,7 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
"integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pify": "^3.0.0"
},
@@ -6233,6 +6881,7 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -6242,17 +6891,42 @@
"node": ">= 6"
}
},
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/regenerate-unicode-properties": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz",
- "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"regenerate": "^1.4.2"
},
@@ -6261,29 +6935,34 @@
}
},
"node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "dev": true
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "license": "MIT"
},
"node_modules/regenerator-transform": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
"integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.8.4"
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
- "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "set-function-name": "^2.0.0"
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -6293,15 +6972,16 @@
}
},
"node_modules/regexpu-core": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
- "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/regjsgen": "^0.8.0",
"regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsparser": "^0.9.1",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.1.0"
},
@@ -6312,27 +6992,40 @@
"node_modules/register-service-worker": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/register-service-worker/-/register-service-worker-1.7.2.tgz",
- "integrity": "sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A=="
+ "integrity": "sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A==",
+ "license": "MIT"
+ },
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/require-from-string": {
@@ -6340,23 +7033,28 @@
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-core-module": "^2.13.0",
+ "is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -6366,15 +7064,17 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
+ "license": "MIT",
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
@@ -6384,7 +7084,9 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
+ "license": "ISC",
"dependencies": {
"glob": "^7.1.3"
},
@@ -6396,10 +7098,11 @@
}
},
"node_modules/rollup": {
- "version": "3.29.4",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
- "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "version": "3.29.5",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
+ "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
"dev": true,
+ "license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -6430,19 +7133,22 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"queue-microtask": "^1.2.2"
}
},
"node_modules/safe-array-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
- "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1",
- "has-symbols": "^1.0.3",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
"isarray": "^2.0.5"
},
"engines": {
@@ -6470,61 +7176,111 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
- "node_modules/safe-regex-test": {
+ "node_modules/safe-push-apply": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "is-regex": "^1.1.4"
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
},
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
}
},
"node_modules/set-function-length": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
- "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "define-data-property": "^1.1.1",
- "get-intrinsic": "^1.2.1",
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.0"
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/set-function-name": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
- "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "define-data-property": "^1.0.1",
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.0"
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -6536,6 +7292,7 @@
"integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
"dev": true,
"hasInstallScript": true,
+ "license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.2",
@@ -6558,6 +7315,7 @@
"resolved": "https://registry.npmjs.org/sharp-ico/-/sharp-ico-0.1.5.tgz",
"integrity": "sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"decode-ico": "*",
"ico-endec": "*",
@@ -6569,6 +7327,7 @@
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
@@ -6581,28 +7340,95 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/shell-quote": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
- "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6626,7 +7452,8 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/simple-get": {
"version": "4.0.1",
@@ -6647,6 +7474,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@@ -6658,6 +7486,7 @@
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
@@ -6666,30 +7495,44 @@
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
+ "node_modules/smob": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
+ "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
"dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 8"
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -6699,58 +7542,78 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
"integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "dev": true
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
+ "license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-license-ids": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
- "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
- "dev": true
+ "version": "3.0.21",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
+ "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
+ "dev": true,
+ "license": "CC0-1.0"
},
"node_modules/streamx": {
- "version": "2.15.6",
- "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz",
- "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==",
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz",
+ "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-fifo": "^1.1.0",
- "queue-tick": "^1.0.1"
+ "fast-fifo": "^1.3.2",
+ "text-decoder": "^1.1.0"
+ },
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
}
},
"node_modules/string_decoder": {
@@ -6758,39 +7621,50 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string.prototype.matchall": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
- "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==",
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
- "regexp.prototype.flags": "^1.5.0",
- "set-function-name": "^2.0.0",
- "side-channel": "^1.0.4"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.padend": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz",
- "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==",
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz",
+ "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -6800,14 +7674,19 @@
}
},
"node_modules/string.prototype.trim": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz",
- "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==",
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -6817,28 +7696,37 @@
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz",
- "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz",
- "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6849,6 +7737,7 @@
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
"integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"get-own-enumerable-property-symbols": "^3.0.0",
"is-obj": "^1.0.1",
@@ -6863,6 +7752,7 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
@@ -6875,6 +7765,7 @@
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -6884,6 +7775,7 @@
"resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
"integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
}
@@ -6893,6 +7785,7 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
},
@@ -6905,6 +7798,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -6917,6 +7811,7 @@
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -6925,21 +7820,26 @@
}
},
"node_modules/tar-fs": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
- "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz",
+ "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^3.1.5"
+ },
+ "optionalDependencies": {
+ "bare-fs": "^4.0.1",
+ "bare-path": "^3.0.0"
}
},
"node_modules/tar-stream": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
- "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
+ "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"b4a": "^1.6.4",
"fast-fifo": "^1.2.0",
@@ -6951,6 +7851,7 @@
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
"integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -6960,6 +7861,7 @@
"resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz",
"integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-stream": "^2.0.0",
"temp-dir": "^2.0.0",
@@ -6973,23 +7875,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/tempy/node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/tempy/node_modules/type-fest": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
@@ -6998,10 +7889,11 @@
}
},
"node_modules/terser": {
- "version": "5.26.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz",
- "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==",
+ "version": "5.39.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
+ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -7015,38 +7907,36 @@
"node": ">=10"
}
},
- "node_modules/terser/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "node_modules/text-decoder": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
},
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/to-data-view": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz",
"integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
- "engines": {
- "node": ">=4"
- }
+ "license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
@@ -7054,17 +7944,29 @@
"node": ">=8.0"
}
},
+ "node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tslib": "^1.8.1"
},
@@ -7080,6 +7982,7 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
},
@@ -7092,6 +7995,7 @@
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1"
},
@@ -7104,6 +8008,7 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
@@ -7112,29 +8017,32 @@
}
},
"node_modules/typed-array-buffer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
- "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1",
- "is-typed-array": "^1.1.10"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
- "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -7144,16 +8052,19 @@
}
},
"node_modules/typed-array-byte-offset": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
- "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
},
"engines": {
"node": ">= 0.4"
@@ -7163,14 +8074,21 @@
}
},
"node_modules/typed-array-length": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
- "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "is-typed-array": "^1.1.9"
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7181,6 +8099,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"devOptional": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -7189,37 +8108,35 @@
"node": ">=4.2.0"
}
},
- "node_modules/ufo": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz",
- "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==",
- "dev": true
- },
"node_modules/unbox-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
- "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bound": "^1.0.3",
"has-bigints": "^1.0.2",
- "has-symbols": "^1.0.3",
- "which-boxed-primitive": "^1.0.2"
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/unconfig": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.3.11.tgz",
- "integrity": "sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==",
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.3.13.tgz",
+ "integrity": "sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@antfu/utils": "^0.7.6",
- "defu": "^6.1.2",
- "jiti": "^1.20.0",
- "mlly": "^1.4.2"
+ "@antfu/utils": "^0.7.7",
+ "defu": "^6.1.4",
+ "jiti": "^1.21.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
@@ -7229,13 +8146,15 @@
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -7245,6 +8164,7 @@
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
"integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^2.0.0",
"unicode-property-aliases-ecmascript": "^2.0.0"
@@ -7254,10 +8174,11 @@
}
},
"node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -7267,6 +8188,7 @@
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -7276,6 +8198,7 @@
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
"integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"crypto-random-string": "^2.0.0"
},
@@ -7288,6 +8211,7 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
@@ -7297,15 +8221,16 @@
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4",
"yarn": "*"
}
},
"node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"dev": true,
"funding": [
{
@@ -7321,9 +8246,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -7337,6 +8263,7 @@
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
@@ -7345,23 +8272,26 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/vite": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
- "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
+ "version": "4.5.12",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.12.tgz",
+ "integrity": "sha512-qrMwavANtSz91nDy3zEiUHMtL09x0mniQsSMvDkNxuCBM1W5vriJ22hEmwTth6DhLSWsZnHBT0yHFAQXt6efGA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"esbuild": "^0.18.10",
"postcss": "^8.4.27",
@@ -7417,6 +8347,7 @@
"resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.17.5.tgz",
"integrity": "sha512-UxRNPiJBzh4tqU/vc8G2TxmrUTzT6BqvSzhszLk62uKsf+npXdvLxGDz9C675f4BJi6MbD2tPnJhi5txlMzxbQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
@@ -7436,274 +8367,355 @@
"workbox-window": "^7.0.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/@apideck/better-ajv-errors": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
- "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
- "dev": true,
- "dependencies": {
- "json-schema": "^0.4.0",
- "jsonpointer": "^5.0.0",
- "leven": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "ajv": ">=8"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/@rollup/plugin-babel": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
- "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
- "dev": true,
+ "node_modules/vue": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
+ "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.10.4",
- "@rollup/pluginutils": "^3.1.0"
- },
- "engines": {
- "node": ">= 10.0.0"
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-sfc": "3.5.13",
+ "@vue/runtime-dom": "3.5.13",
+ "@vue/server-renderer": "3.5.13",
+ "@vue/shared": "3.5.13"
},
"peerDependencies": {
- "@babel/core": "^7.0.0",
- "@types/babel__core": "^7.1.9",
- "rollup": "^1.20.0||^2.0.0"
+ "typescript": "*"
},
"peerDependenciesMeta": {
- "@types/babel__core": {
+ "typescript": {
"optional": true
}
}
},
- "node_modules/vite-plugin-pwa/node_modules/@rollup/plugin-node-resolve": {
- "version": "11.2.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz",
- "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==",
+ "node_modules/vue-cookies": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.6.tgz",
+ "integrity": "sha512-e2kYaHj1Y/zVsBSM3KWlOoVJ5o3l4QZjytNU7xdCgmkw3521CMUerqHekBGZKXXC1oRxYljBeeOK2SCel6cKuw==",
+ "license": "MIT"
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "9.4.3",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+ "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@rollup/pluginutils": "^3.1.0",
- "@types/resolve": "1.17.1",
- "builtin-modules": "^3.1.0",
- "deepmerge": "^4.2.2",
- "is-module": "^1.0.0",
- "resolve": "^1.19.0"
+ "debug": "^4.3.4",
+ "eslint-scope": "^7.1.1",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.3.1",
+ "esquery": "^1.4.0",
+ "lodash": "^4.17.21",
+ "semver": "^7.3.6"
},
"engines": {
- "node": ">= 10.0.0"
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0"
+ "eslint": ">=6.0.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/@rollup/plugin-replace": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
- "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
+ "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "@rollup/pluginutils": "^3.1.0",
- "magic-string": "^0.25.7"
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
},
- "peerDependencies": {
- "rollup": "^1.20.0 || ^2.0.0"
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/vite-plugin-pwa/node_modules/@rollup/pluginutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
- "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "node_modules/vue-eslint-parser/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/vue-request": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vue-request/-/vue-request-2.0.4.tgz",
+ "integrity": "sha512-+Tu5rDy6ItF9UdD21Mmbjiq5Pq6NZSN9juH72hNQTMn1whHh4KZPTKWVLK2YS4nzbuEnPs+82G91AA2Fgd93mg==",
+ "license": "MIT",
"dependencies": {
- "@types/estree": "0.0.39",
- "estree-walker": "^1.0.1",
- "picomatch": "^2.2.2"
+ "vue-demi": "latest"
},
"engines": {
- "node": ">= 8.0.0"
+ "node": ">=14"
},
"peerDependencies": {
- "rollup": "^1.20.0||^2.0.0"
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^2.0.0 || >=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
}
},
- "node_modules/vite-plugin-pwa/node_modules/@types/estree": {
- "version": "0.0.39",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
- "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
- "dev": true
+ "node_modules/vue-request/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
},
- "node_modules/vite-plugin-pwa/node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
+ "node_modules/vue-router": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
+ "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==",
+ "license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
+ "@vue/devtools-api": "^6.6.4"
},
"funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.2.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "node_modules/vue-template-compiler": {
+ "version": "2.7.16",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
+ "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==",
"dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "license": "MIT",
+ "dependencies": {
+ "de-indent": "^1.0.2",
+ "he": "^1.2.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/estree-walker": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
- "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
- "dev": true
- },
- "node_modules/vite-plugin-pwa/node_modules/jest-worker": {
- "version": "26.6.2",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
- "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "node_modules/vue-tsc": {
+ "version": "1.8.27",
+ "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz",
+ "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/node": "*",
- "merge-stream": "^2.0.0",
- "supports-color": "^7.0.0"
+ "@volar/typescript": "~1.11.1",
+ "@vue/language-core": "1.8.27",
+ "semver": "^7.5.4"
},
- "engines": {
- "node": ">= 10.13.0"
+ "bin": {
+ "vue-tsc": "bin/vue-tsc.js"
+ },
+ "peerDependencies": {
+ "typescript": "*"
}
},
- "node_modules/vite-plugin-pwa/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
+ "node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
},
- "node_modules/vite-plugin-pwa/node_modules/magic-string": {
- "version": "0.25.9",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
- "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "sourcemap-codec": "^1.4.8"
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
}
},
- "node_modules/vite-plugin-pwa/node_modules/pretty-bytes": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",
- "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==",
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "node_modules/vite-plugin-pwa/node_modules/rollup": {
- "version": "2.79.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
"dev": true,
- "bin": {
- "rollup": "dist/bin/rollup"
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
},
"engines": {
- "node": ">=10.0.0"
+ "node": ">= 0.4"
},
- "optionalDependencies": {
- "fsevents": "~2.3.2"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite-plugin-pwa/node_modules/rollup-plugin-terser": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
- "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
- "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser",
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.10.4",
- "jest-worker": "^26.2.1",
- "serialize-javascript": "^4.0.0",
- "terser": "^5.0.0"
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
},
- "peerDependencies": {
- "rollup": "^2.0.0"
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite-plugin-pwa/node_modules/serialize-javascript": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
- "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "randombytes": "^2.1.0"
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite-plugin-pwa/node_modules/source-map": {
- "version": "0.8.0-beta.0",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
- "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "whatwg-url": "^7.0.0"
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
- "node": ">= 8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/vite-plugin-pwa/node_modules/tr46": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
- "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/webidl-conversions": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
- "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
- "dev": true
+ "node_modules/workbox": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/workbox/-/workbox-0.0.0.tgz",
+ "integrity": "sha512-/I5JIWHK18DDGGoXOZgOkOFLsiMQZlHLnwEzw328ZMU4TA21yFCw11YEnZ1CsOnSazl0DMbFmLJ6q5hpQhP/aQ==",
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "6.x.x"
+ }
},
- "node_modules/vite-plugin-pwa/node_modules/whatwg-url": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
- "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "node_modules/workbox-background-sync": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
+ "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "lodash.sortby": "^4.7.0",
- "tr46": "^1.0.1",
- "webidl-conversions": "^4.0.2"
+ "idb": "^7.0.1",
+ "workbox-core": "7.3.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/workbox-broadcast-update": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.0.0.tgz",
- "integrity": "sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ==",
+ "node_modules/workbox-broadcast-update": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz",
+ "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.0.0"
+ "workbox-core": "7.3.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/workbox-build": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.0.0.tgz",
- "integrity": "sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==",
+ "node_modules/workbox-build": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz",
+ "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@apideck/better-ajv-errors": "^0.3.1",
- "@babel/core": "^7.11.1",
+ "@babel/core": "^7.24.4",
"@babel/preset-env": "^7.11.0",
"@babel/runtime": "^7.11.2",
"@rollup/plugin-babel": "^5.2.0",
- "@rollup/plugin-node-resolve": "^11.2.1",
+ "@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^2.4.1",
+ "@rollup/plugin-terser": "^0.4.3",
"@surma/rollup-plugin-off-main-thread": "^2.2.3",
"ajv": "^8.6.0",
"common-tags": "^1.8.0",
@@ -7713,418 +8725,345 @@
"lodash": "^4.17.20",
"pretty-bytes": "^5.3.0",
"rollup": "^2.43.1",
- "rollup-plugin-terser": "^7.0.0",
"source-map": "^0.8.0-beta.0",
"stringify-object": "^3.3.0",
"strip-comments": "^2.0.1",
"tempy": "^0.6.0",
"upath": "^1.2.0",
- "workbox-background-sync": "7.0.0",
- "workbox-broadcast-update": "7.0.0",
- "workbox-cacheable-response": "7.0.0",
- "workbox-core": "7.0.0",
- "workbox-expiration": "7.0.0",
- "workbox-google-analytics": "7.0.0",
- "workbox-navigation-preload": "7.0.0",
- "workbox-precaching": "7.0.0",
- "workbox-range-requests": "7.0.0",
- "workbox-recipes": "7.0.0",
- "workbox-routing": "7.0.0",
- "workbox-strategies": "7.0.0",
- "workbox-streams": "7.0.0",
- "workbox-sw": "7.0.0",
- "workbox-window": "7.0.0"
+ "workbox-background-sync": "7.3.0",
+ "workbox-broadcast-update": "7.3.0",
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-google-analytics": "7.3.0",
+ "workbox-navigation-preload": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-range-requests": "7.3.0",
+ "workbox-recipes": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0",
+ "workbox-streams": "7.3.0",
+ "workbox-sw": "7.3.0",
+ "workbox-window": "7.3.0"
},
"engines": {
"node": ">=16.0.0"
}
},
- "node_modules/vite-plugin-pwa/node_modules/workbox-build/node_modules/pretty-bytes": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
- "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
+ "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema": "^0.4.0",
+ "jsonpointer": "^5.0.0",
+ "leven": "^3.1.0"
+ },
"engines": {
- "node": ">=6"
+ "node": ">=10"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-cacheable-response": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.0.0.tgz",
- "integrity": "sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g==",
- "dev": true,
- "dependencies": {
- "workbox-core": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-expiration": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.0.0.tgz",
- "integrity": "sha512-MLK+fogW+pC3IWU9SFE+FRStvDVutwJMR5if1g7oBJx3qwmO69BNoJQVaMXq41R0gg3MzxVfwOGKx3i9P6sOLQ==",
- "dev": true,
- "dependencies": {
- "idb": "^7.0.1",
- "workbox-core": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-google-analytics": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.0.0.tgz",
- "integrity": "sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==",
- "dev": true,
- "dependencies": {
- "workbox-background-sync": "7.0.0",
- "workbox-core": "7.0.0",
- "workbox-routing": "7.0.0",
- "workbox-strategies": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-navigation-preload": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.0.0.tgz",
- "integrity": "sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==",
- "dev": true,
- "dependencies": {
- "workbox-core": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-range-requests": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.0.0.tgz",
- "integrity": "sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ==",
- "dev": true,
- "dependencies": {
- "workbox-core": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-recipes": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.0.0.tgz",
- "integrity": "sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww==",
- "dev": true,
- "dependencies": {
- "workbox-cacheable-response": "7.0.0",
- "workbox-core": "7.0.0",
- "workbox-expiration": "7.0.0",
- "workbox-precaching": "7.0.0",
- "workbox-routing": "7.0.0",
- "workbox-strategies": "7.0.0"
+ "peerDependencies": {
+ "ajv": ">=8"
}
},
- "node_modules/vite-plugin-pwa/node_modules/workbox-streams": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.0.0.tgz",
- "integrity": "sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ==",
+ "node_modules/workbox-build/node_modules/@rollup/plugin-babel": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
+ "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.0.0",
- "workbox-routing": "7.0.0"
- }
- },
- "node_modules/vite-plugin-pwa/node_modules/workbox-sw": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.0.0.tgz",
- "integrity": "sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==",
- "dev": true
- },
- "node_modules/vue": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz",
- "integrity": "sha512-d4oBctG92CRO1cQfVBZp6WJAs0n8AK4Xf5fNjQCBeKCvMI1efGQ5E3Alt1slFJS9fZuPcFoiAiqFvQlv1X7t/w==",
- "dependencies": {
- "@vue/compiler-dom": "3.3.11",
- "@vue/compiler-sfc": "3.3.11",
- "@vue/runtime-dom": "3.3.11",
- "@vue/server-renderer": "3.3.11",
- "@vue/shared": "3.3.11"
+ "@babel/helper-module-imports": "^7.10.4",
+ "@rollup/pluginutils": "^3.1.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
},
"peerDependencies": {
- "typescript": "*"
+ "@babel/core": "^7.0.0",
+ "@types/babel__core": "^7.1.9",
+ "rollup": "^1.20.0||^2.0.0"
},
"peerDependenciesMeta": {
- "typescript": {
+ "@types/babel__core": {
"optional": true
}
}
},
- "node_modules/vue-cookies": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.3.tgz",
- "integrity": "sha512-VBRsyRMVdahBgFfh389TMHPmDdr4URDJNMk4FKSCfuNITs7+jitBDhwyL4RJd3WUsfOYNNjPAkfbehyH9AFuoA=="
+ "node_modules/workbox-build/node_modules/@rollup/plugin-replace": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
+ "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.1.0",
+ "magic-string": "^0.25.7"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0 || ^2.0.0"
+ }
},
- "node_modules/vue-eslint-parser": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",
- "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==",
+ "node_modules/workbox-build/node_modules/@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "debug": "^4.3.4",
- "eslint-scope": "^7.1.1",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
- "lodash": "^4.17.21",
- "semver": "^7.3.6"
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
},
"engines": {
- "node": "^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
+ "node": ">= 8.0.0"
},
"peerDependencies": {
- "eslint": ">=6.0.0"
+ "rollup": "^1.20.0||^2.0.0"
}
},
- "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
- "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "node_modules/workbox-build/node_modules/@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/vue-eslint-parser/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "node_modules/workbox-build/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true,
- "engines": {
- "node": ">=4.0"
- }
+ "license": "MIT"
},
- "node_modules/vue-request": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/vue-request/-/vue-request-2.0.4.tgz",
- "integrity": "sha512-+Tu5rDy6ItF9UdD21Mmbjiq5Pq6NZSN9juH72hNQTMn1whHh4KZPTKWVLK2YS4nzbuEnPs+82G91AA2Fgd93mg==",
+ "node_modules/workbox-build/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "vue-demi": "latest"
- },
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.0.0-rc.1",
- "vue": "^2.0.0 || >=3.0.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- }
+ "sourcemap-codec": "^1.4.8"
}
},
- "node_modules/vue-request/node_modules/vue-demi": {
- "version": "0.14.6",
- "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
- "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
- "hasInstallScript": true,
- "bin": {
- "vue-demi-fix": "bin/vue-demi-fix.js",
- "vue-demi-switch": "bin/vue-demi-switch.js"
- },
+ "node_modules/workbox-build/node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=6"
},
"funding": {
- "url": "https://github.com/sponsors/antfu"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.0.0-rc.1",
- "vue": "^3.0.0-0 || ^2.6.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- }
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vue-router": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",
- "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==",
- "dependencies": {
- "@vue/devtools-api": "^6.5.0"
+ "node_modules/workbox-build/node_modules/rollup": {
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
},
- "funding": {
- "url": "https://github.com/sponsors/posva"
+ "engines": {
+ "node": ">=10.0.0"
},
- "peerDependencies": {
- "vue": "^3.2.0"
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
}
},
- "node_modules/vue-template-compiler": {
- "version": "2.7.15",
- "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.15.tgz",
- "integrity": "sha512-yQxjxMptBL7UAog00O8sANud99C6wJF+7kgbcwqkvA38vCGF7HWE66w0ZFnS/kX5gSoJr/PQ4/oS3Ne2pW37Og==",
+ "node_modules/workbox-cacheable-response": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz",
+ "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "de-indent": "^1.0.2",
- "he": "^1.2.0"
+ "workbox-core": "7.3.0"
}
},
- "node_modules/vue-tsc": {
- "version": "1.8.25",
- "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.25.tgz",
- "integrity": "sha512-lHsRhDc/Y7LINvYhZ3pv4elflFADoEOo67vfClAfF2heVHpHmVquLSjojgCSIwzA4F0Pc4vowT/psXCYcfk+iQ==",
- "dev": true,
- "dependencies": {
- "@volar/typescript": "~1.11.1",
- "@vue/language-core": "1.8.25",
- "semver": "^7.5.4"
- },
- "bin": {
- "vue-tsc": "bin/vue-tsc.js"
- },
- "peerDependencies": {
- "typescript": "*"
- }
+ "node_modules/workbox-core": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz",
+ "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==",
+ "license": "MIT"
},
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "node_modules/workbox-expiration": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz",
+ "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
+ "idb": "^7.0.1",
+ "workbox-core": "7.3.0"
}
},
- "node_modules/which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "node_modules/workbox-google-analytics": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz",
+ "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "workbox-background-sync": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
- "node_modules/which-typed-array": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
- "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
+ "node_modules/workbox-navigation-preload": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz",
+ "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.4",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "workbox-core": "7.3.0"
}
},
- "node_modules/workbox": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/workbox/-/workbox-0.0.0.tgz",
- "integrity": "sha512-/I5JIWHK18DDGGoXOZgOkOFLsiMQZlHLnwEzw328ZMU4TA21yFCw11YEnZ1CsOnSazl0DMbFmLJ6q5hpQhP/aQ==",
+ "node_modules/workbox-precaching": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz",
+ "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==",
+ "license": "MIT",
"dependencies": {
- "babel-runtime": "6.x.x"
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
- "node_modules/workbox-background-sync": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.0.0.tgz",
- "integrity": "sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==",
+ "node_modules/workbox-range-requests": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz",
+ "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "idb": "^7.0.1",
- "workbox-core": "7.0.0"
+ "workbox-core": "7.3.0"
}
},
- "node_modules/workbox-core": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.0.0.tgz",
- "integrity": "sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ=="
- },
- "node_modules/workbox-precaching": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.0.0.tgz",
- "integrity": "sha512-EC0vol623LJqTJo1mkhD9DZmMP604vHqni3EohhQVwhJlTgyKyOkMrZNy5/QHfOby+39xqC01gv4LjOm4HSfnA==",
+ "node_modules/workbox-recipes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz",
+ "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.0.0",
- "workbox-routing": "7.0.0",
- "workbox-strategies": "7.0.0"
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
}
},
"node_modules/workbox-routing": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.0.0.tgz",
- "integrity": "sha512-8YxLr3xvqidnbVeGyRGkaV4YdlKkn5qZ1LfEePW3dq+ydE73hUUJJuLmGEykW3fMX8x8mNdL0XrWgotcuZjIvA==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz",
+ "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==",
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.0.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/workbox-strategies": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.0.0.tgz",
- "integrity": "sha512-dg3qJU7tR/Gcd/XXOOo7x9QoCI9nk74JopaJaYAQ+ugLi57gPsXycVdBnYbayVj34m6Y8ppPwIuecrzkpBVwbA==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz",
+ "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==",
+ "license": "MIT",
"dependencies": {
- "workbox-core": "7.0.0"
+ "workbox-core": "7.3.0"
}
},
+ "node_modules/workbox-streams": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz",
+ "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0"
+ }
+ },
+ "node_modules/workbox-sw": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz",
+ "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/workbox-window": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.0.0.tgz",
- "integrity": "sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA==",
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz",
+ "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/trusted-types": "^2.0.2",
- "workbox-core": "7.0.0"
+ "workbox-core": "7.3.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=12"
}
},
"node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
diff --git a/dashboard/package.json b/dashboard/package.json
index 32a742c2..71e65894 100644
--- a/dashboard/package.json
+++ b/dashboard/package.json
@@ -13,13 +13,14 @@
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
+ "@primeuix/themes": "^1.0.1",
"@types/pako": "^2.0.3",
"axios": "^1.6.2",
"chart.js": "^4.4.1",
"js-sha256": "^0.11.0",
"pako": "^2.1.0",
"primeicons": "^6.0.1",
- "primevue": "^3.49.0",
+ "primevue": "^4.3.3",
"register-service-worker": "^1.7.2",
"vue": "^3.2.47",
"vue-cookies": "^1.8.3",
diff --git a/dashboard/src/App.vue b/dashboard/src/App.vue
index f7961309..d4d35f6f 100644
--- a/dashboard/src/App.vue
+++ b/dashboard/src/App.vue
@@ -3,7 +3,9 @@ import { computed, inject, nextTick, type Ref } from 'vue'
import { RouterLink, RouterView } from 'vue-router'
import axios from 'axios'
import Button from 'primevue/button'
-import Dropdown from 'primevue/dropdown'
+import ConfirmDialog from 'primevue/confirmdialog'
+import ScrollTop from 'primevue/scrolltop'
+import Select from 'primevue/select'
import Toast from 'primevue/toast'
import { useToast } from 'primevue/usetoast'
import { type Lang, avaliableLangs, getLang, setLang, tr, langNameMap } from '@/lang'
@@ -54,7 +56,7 @@ const selectedLang = computed({
-
{{ langNameMap[slotProps.option.toString()] }}
-
+
-
-
-
-
-
-
+
+
+
@@ -102,6 +120,14 @@ const selectedLang = computed({
AGPL-3.0 License
+
+
+
+
+
+
+
+
@@ -115,7 +141,7 @@ const selectedLang = computed({
height: 4rem;
padding-left: 2rem;
padding-right: 1rem;
- background-color: color-mix(in srgb, var(--primary-50) 30%, transparent);
+ background-color: color-mix(in srgb, var(--p-primary-50) 30%, transparent);
box-shadow: #0008 0 0 1rem -0.5rem;
backdrop-filter: blur(0.4rem);
}
@@ -135,7 +161,7 @@ const selectedLang = computed({
}
.nav-login {
- color: var(--primary-color);
+ color: var(--p-primary-color);
text-decoration: none;
}
@@ -193,9 +219,9 @@ const selectedLang = computed({
#footer {
padding: 2rem;
- font-family: var(--font-family);
- color: var(--primary-color-text);
- background-color: var(--primary-color);
+ font-family: var(--p-font-family);
+ color: var(--p-primary-color-text);
+ background-color: var(--p-primary-color);
}
#footer > * {
@@ -203,20 +229,20 @@ const selectedLang = computed({
}
#footer a {
- color: var(--primary-100);
+ color: var(--p-primary-100);
text-decoration: none;
transition: 0.4s color, 0.2s background-color ease;
}
#footer a:hover {
- color: var(--highlight-text-color);
- background-color: var(--highlight-bg);
+ color: var(--p-highlight-color);
+ background-color: var(--p-highlight-background);
text-decoration: underline;
}
@media (prefers-color-scheme: dark) {
#header {
- background-color: color-mix(in srgb, var(--primary-50) 10%, transparent);
+ background-color: color-mix(in srgb, var(--p-primary-50) 10%, transparent);
}
}
diff --git a/dashboard/src/api/v0.ts b/dashboard/src/api/v0.ts
index bcbf3d4a..19e0f65f 100644
--- a/dashboard/src/api/v0.ts
+++ b/dashboard/src/api/v0.ts
@@ -55,6 +55,23 @@ export interface TokenRes {
token: string
}
+export enum UserPermission {
+ BASIC = 1 << 0,
+ SUBSCRIBE = 1 << 1,
+ LOG = 1 << 2,
+ DEBUG = 1 << 3,
+ FULL_CONFIG = 1 << 4,
+ CLUSTER = 1 << 5,
+ STORAGE = 1 << 6,
+ BYPASS_LIMIT = 1 << 7,
+ ROOT = 1 << 31,
+}
+
+export interface UserInfoRes {
+ name: string
+ permissions: number
+}
+
export interface PingRes {
version: string
time: string
@@ -94,6 +111,15 @@ async function requestToken(
return res.data.token
}
+export async function getUserInfo(token: string): Promise {
+ const res = await axios.get(`/api/v0/user_info`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ })
+ return res.data
+}
+
export async function ping(token?: string): Promise {
const res = await axios.get(`/api/v0/ping`, {
headers: {
@@ -113,7 +139,7 @@ export async function getStatus(token?: string | null): Promise {
}
export async function getStat(name: string, token?: string | null): Promise {
- const res = await axios.get(`/api/v0/stat/${name}`, {
+ const res = await axios.get(`/api/v0/stat/storage/${name}`, {
headers: {
Authorization: token ? `Bearer ${token}` : undefined,
},
@@ -447,3 +473,210 @@ export async function getLogFileURL(
u.searchParams.set('_t', tk)
return u.toString()
}
+
+export interface Config {
+ public_host: string
+ public_port: number
+ host: string
+ port: number
+ use_cert: boolean
+ allow_unsecure_connection: boolean
+ trusted_x_forwarded_for: boolean
+
+ only_gc_when_start: boolean
+ sync_interval: number
+ download_max_conn: number
+ max_reconnect_count: number
+
+ log_slots: number
+ no_access_log: boolean
+ access_log_slots: number
+
+ clusters: { [name: string]: ClusterOptions }
+ storages: StorageOption[]
+ certificates: CertificateConfig[]
+ tunneler: TunnelConfig
+ cache: CacheConfig
+ serve_limit: ServeLimitConfig
+ api_rate_limit: APIRateLimitConfig
+ notification: NotificationConfig
+ dashboard: DashboardConfig
+ github_api: GithubAPIConfig
+ database: DatabaseConfig
+ hijack: HijackConfig
+ webdav_users: { [name: string]: WebDavUser }
+ advanced: AdvancedConfig
+}
+
+export interface ClusterOptions {
+ id: string
+ secret: string
+ byoc: boolean
+ public_hosts: string[]
+ server: string
+ skip_signature_check: boolean
+ storages: string[]
+}
+
+interface LocalStorageOption {
+ type: 'local'
+ cache_path: string
+ compressor: string
+}
+
+interface MountStorageOption {
+ type: 'mount'
+ path: string
+ redirect_base: string
+ pre_gen_measures: boolean
+}
+
+type WebDavStorageOption = {
+ type: 'webdav'
+ max_conn: number
+ max_upload_rate: number
+ max_download_rate: number
+ pre_gen_measures: boolean
+ follow_redirect: boolean
+ redirect_link_cache: number
+ alias?: string
+} & WebDavUser
+
+export interface WebDavUser {
+ endpoint?: string
+ username?: string
+ password?: string
+}
+
+export type StorageOption = {
+ id: string
+ weight: number
+} & (LocalStorageOption | MountStorageOption | WebDavStorageOption)
+
+export interface CertificateConfig {
+ cert: string
+ key: string
+}
+
+export interface TunnelConfig {
+ enable: boolean
+ tunnel_program: string
+ output_regex: string
+}
+
+export type CacheConfig =
+ | {
+ type: 'no-cache' | 'memory'
+ }
+ | {
+ type: 'redis'
+ network: string
+ addr: string
+ client_name: string
+ username: string
+ password: string
+ }
+
+export interface ServeLimitConfig {
+ enable: boolean
+ max_conn: number
+ upload_rate: number
+}
+
+export interface RateLimit {
+ per_minute: number
+ per_hour: number
+}
+
+export interface APIRateLimitConfig {
+ anonymous: RateLimit
+ logged: RateLimit
+}
+
+export interface NotificationConfig {
+ enable_email: boolean
+ email_smtp: string
+ email_smtp_encryption: string
+ email_sender: string
+ email_sender_password: string
+ enable_webhook: boolean
+}
+
+export interface DashboardConfig {
+ enable: boolean
+ username: string
+ password: string
+ pwa_name: string
+ pwa_short_name: string
+ pwa_description: string
+ notification_subject: string
+}
+
+export interface GithubAPIConfig {
+ update_check_interval: number
+ authorization: string
+}
+
+export interface DatabaseConfig {
+ driver: string
+ data_source_name: string
+}
+
+export interface UserItem {
+ username: string
+ password: string
+}
+
+export interface HijackConfig {
+ enable: boolean
+ enable_local_cache: boolean
+ local_cache_path: string
+ require_auth: boolean
+ auth_users: UserItem[]
+}
+
+export interface AdvancedConfig {
+ // Unsupported
+}
+
+export async function getConfig(token: string): Promise {
+ const res = await axios.get(`/api/v0/config`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ })
+ return res.data
+}
+
+export async function putConfig(token: string, config: Config): Promise {
+ await axios.put(`/api/v0/config`, JSON.stringify(config), {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json',
+ },
+ })
+}
+
+export enum ClusterStatus {
+ DISCONNECTED = 0,
+ CONNECTING = 1,
+ DISABLED = 2,
+ ENABLING = 3,
+ ENABLED = 4,
+}
+
+export interface ClusterStatusRes {
+ [name: string]: {
+ status: ClusterStatus
+ sync: boolean
+ }
+}
+
+export async function getClusterStatus(token: string): Promise {
+ const res = await axios.get(`/api/v0/cluster/status`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ })
+ return res.data
+}
diff --git a/dashboard/src/assets/base.css b/dashboard/src/assets/base.css
index 59d8317b..0a2423a3 100644
--- a/dashboard/src/assets/base.css
+++ b/dashboard/src/assets/base.css
@@ -7,6 +7,8 @@
:root {
font-size: 16px;
--dialog-width: 60rem;
+ --table-row-bg-a: var(--p-surface-100);
+ --table-row-bg-b: var(--p-surface-200);
}
body {
@@ -26,3 +28,10 @@ body {
--dialog-width: 100vw;
}
}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --table-row-bg-a: var(--p-surface-800);
+ --table-row-bg-b: var(--p-surface-700);
+ }
+}
diff --git a/dashboard/src/assets/lang/en-US.json b/dashboard/src/assets/lang/en-US.json
index 8cf31bd7..e3090e41 100644
--- a/dashboard/src/assets/lang/en-US.json
+++ b/dashboard/src/assets/lang/en-US.json
@@ -59,11 +59,92 @@
"scopes": "Scopes",
"auth-header": "Auth Header",
"configure": "Configure webhook"
+ },
+
+ "configure": "Configure",
+ "configures": {
+ "hostport": "Host and Port",
+ "sync": "Synchronize",
+ "logs": "Logs",
+ "clusters": "Clusters",
+ "storages": "Storages",
+ "tunneler": "Tunneler",
+ "cache": "Cache",
+ "serve_limit": "Serve Limit",
+
+ "item": {
+ "public_host": "Public Host",
+ "public_port": "Public Port",
+ "host": "Host",
+ "port": "Port",
+ "use_cert": "Use Certification",
+ "trusted_x_forwarded_for": "Trust X-Forwarded-For",
+
+ "only_gc_when_start": "Only cleanup when start",
+ "sync_interval": "Synchronize Interval",
+ "download_max_conn": "Max Download Connection",
+ "max_reconnect_count": "Max Reconnect Count",
+
+ "log_slots": "Log Slots",
+ "enable_access_log": "Enable Access Log",
+ "access_log_slots": "Access Log Slots",
+
+ "cluster": {
+ "id": "Cluster ID",
+ "secret": "Cluster Secret",
+ "byoc": "Custom Certificate",
+ "public_hosts": "Public Hostnames",
+ "server": "Central Server",
+ "skip_signature_check": "Skip Signature Check",
+ "storages": "Using Storages"
+ },
+
+ "storage": {
+ "type": "Storage Type",
+ "weight": "Weight",
+ "cache_path": "Path",
+ "path": "Path",
+ "redirect_base": "Redirect Base URL",
+ "pre_gen_measures": "Pre-generate mesaures",
+ "max_conn": "Max Connection",
+ "max_upload_rate": "Max Upload Rate",
+ "max_download_rate": "Max Download Rate",
+ "follow_redirect": "Follow Redirect",
+ "redirect_link_cache": "Redirect Link Cache Duration"
+ },
+
+ "tunneler": {
+ "enable": "Enable Tunneler",
+ "tunnel_program": "Tunnel Program",
+ "output_regex": "Output Regex"
+ },
+
+ "cache": {
+ "type": "Cache Type"
+ },
+
+ "serve_limit": {
+ "enable": "Enable Serve Limit",
+ "max_conn": "Max Connection",
+ "upload_rate": "Max Upload Rate"
+ }
+ },
+
+ "confirm": {
+ "remove": "Remove Confirmation",
+ "discard": "Discard Confirmation"
+ }
}
},
"button": {
"enable": "Enable",
- "disable": "Disable"
+ "disable": "Disable",
+ "save": "Save",
+ "saved": "Saved",
+ "refresh": "Refresh",
+ "remove": "Remove",
+ "cancel": "Cancel",
+ "discard": "Discard"
},
"message": {
"server": {
@@ -98,6 +179,12 @@
"filelist": {
"cant.fetch": "Cannot fetch filelist"
}
+ },
+ "configures": {
+ "confirm": {
+ "remove": "Are you sure you want to remove cluster {0}?",
+ "discard": "Are you sure to discard configure changes?"
+ }
}
},
"badge": {
diff --git a/dashboard/src/assets/lang/zh-CN.json b/dashboard/src/assets/lang/zh-CN.json
index b9afb45d..7cefcac3 100644
--- a/dashboard/src/assets/lang/zh-CN.json
+++ b/dashboard/src/assets/lang/zh-CN.json
@@ -59,11 +59,92 @@
"scopes": "域",
"auth-header": "授权标头",
"configure": "配置网络钩子"
+ },
+
+ "configure": "配置",
+ "configures": {
+ "hostport": "主机&端口",
+ "sync": "同步",
+ "logs": "日志",
+ "clusters": "节点",
+ "storages": "存储",
+ "tunneler": "打洞",
+ "cache": "缓存",
+ "serve_limit": "服务限制",
+
+ "item": {
+ "public_host": "公网主机名",
+ "public_port": "公网端口",
+ "host": "主机名",
+ "port": "端口",
+ "use_cert": "使用证书",
+ "trusted_x_forwarded_for": "信任 X-Forwarded-For",
+
+ "only_gc_when_start": "仅在启动时清理",
+ "sync_interval": "同步间隔",
+ "download_max_conn": "最大下载连接数",
+ "max_reconnect_count": "最大重试次数",
+
+ "log_slots": "日志槽位",
+ "enable_access_log": "启用访问日志",
+ "access_log_slots": "访问日志槽位",
+
+ "cluster": {
+ "id": "节点ID",
+ "secret": "节点密钥",
+ "byoc": "自定义证书",
+ "public_hosts": "公开主机名",
+ "server": "主控服务器",
+ "skip_signature_check": "跳过签名检查",
+ "storages": "使用存储"
+ },
+
+ "storage": {
+ "type": "存储类型",
+ "weight": "权重",
+ "cache_path": "路径",
+ "path": "路径",
+ "redirect_base": "重定向基础URL",
+ "pre_gen_measures": "预生成测速文件",
+ "max_conn": "最大连接数",
+ "max_upload_rate": "最大上传速率",
+ "max_download_rate": "最大下载速率",
+ "follow_redirect": "跟随重定向",
+ "redirect_link_cache": "重定向链接缓存时间"
+ },
+
+ "tunneler": {
+ "enable": "启用打洞",
+ "tunnel_program": "打洞程序",
+ "output_regex": "输出正则"
+ },
+
+ "cache": {
+ "type": "缓存类型"
+ },
+
+ "serve_limit": {
+ "enable": "启用服务限制",
+ "max_conn": "最大连接数",
+ "upload_rate": "最大上传速率"
+ }
+ },
+
+ "confirm": {
+ "remove": "移除确认",
+ "discard": "撤销更改?"
+ }
}
},
"button": {
"enable": "启用",
- "disable": "禁用"
+ "disable": "禁用",
+ "save": "保存",
+ "saved": "已保存",
+ "refresh": "刷新",
+ "remove": "移除",
+ "cancel": "取消",
+ "discard": "撤销"
},
"message": {
"server": {
@@ -98,6 +179,12 @@
"filelist": {
"cant.fetch": "无法获取文件列表"
}
+ },
+ "configures": {
+ "confirm": {
+ "remove": "确认删除节点 {0} 吗?",
+ "discard": "确认放弃更改吗?"
+ }
}
},
"badge": {
diff --git a/dashboard/src/assets/main.css b/dashboard/src/assets/main.css
index b4e434ac..23d9ac83 100644
--- a/dashboard/src/assets/main.css
+++ b/dashboard/src/assets/main.css
@@ -25,11 +25,11 @@ a.pi {
}
@media (max-width: 60rem) {
- .p-dropdown .p-dropdown-label.p-inputtext {
+ .p-select .p-select-label.p-inputtext {
padding-left: 0.6rem;
}
- .p-dropdown .p-dropdown-trigger {
+ .p-select .p-select-dropdown {
width: 2.1rem;
}
}
diff --git a/dashboard/src/assets/theme.css b/dashboard/src/assets/theme.css
deleted file mode 100644
index 250da4c1..00000000
--- a/dashboard/src/assets/theme.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import 'primevue/resources/themes/lara-light-green/theme.css' not (prefers-color-scheme: dark);
-@import 'primevue/resources/themes/lara-dark-green/theme.css' (prefers-color-scheme: dark);
diff --git a/dashboard/src/components/FileListCard.vue b/dashboard/src/components/FileListCard.vue
index f097dc79..d06c8f09 100644
--- a/dashboard/src/components/FileListCard.vue
+++ b/dashboard/src/components/FileListCard.vue
@@ -16,7 +16,7 @@ defineEmits<{
- {{ name }}
+
diff --git a/dashboard/src/components/HitsChart.vue b/dashboard/src/components/HitsChart.vue
index e11009a3..1a77e2c1 100644
--- a/dashboard/src/components/HitsChart.vue
+++ b/dashboard/src/components/HitsChart.vue
@@ -65,7 +65,7 @@ const getChartData = () => {
{
label: computed(() => tr('title.hits')),
fill: true,
- borderColor: documentStyle.getPropertyValue('--blue-500'),
+ borderColor: documentStyle.getPropertyValue('--p-blue-500'),
yAxisID: 'y',
tension: 0.3,
data: hits,
@@ -73,7 +73,7 @@ const getChartData = () => {
{
label: computed(() => tr('title.bytes')),
fill: true,
- borderColor: documentStyle.getPropertyValue('--green-500'),
+ borderColor: documentStyle.getPropertyValue('--p-green-500'),
yAxisID: 'y1',
tension: 0.4,
data: bytes,
@@ -84,9 +84,9 @@ const getChartData = () => {
const getChartOptions = () => {
const documentStyle = getComputedStyle(document.documentElement)
- const textColor = documentStyle.getPropertyValue('--text-color')
- const textColorSecondary = documentStyle.getPropertyValue('--text-color-secondary')
- const surfaceBorder = documentStyle.getPropertyValue('--surface-border')
+ const textColor = documentStyle.getPropertyValue('--p-text-color')
+ const textColorSecondary = documentStyle.getPropertyValue('--p-text-color-secondary')
+ const surfaceBorder = documentStyle.getPropertyValue('--p-surface-border')
return {
stacked: false,
diff --git a/dashboard/src/components/StatusButton.vue b/dashboard/src/components/StatusButton.vue
index bbf6fc27..270c0048 100644
--- a/dashboard/src/components/StatusButton.vue
+++ b/dashboard/src/components/StatusButton.vue
@@ -77,7 +77,7 @@ onMounted(() => {
height: 2.7rem;
margin: 0.5rem;
padding: 0;
- border: none;
+ border: none !important;
border-radius: 0.2rem;
font-weight: 800;
overflow: hidden;
@@ -89,23 +89,23 @@ onMounted(() => {
.info-status[status='enabled'] {
--flash-from: #fff;
--flash-to: #11dfc3;
- color: #fff;
- background-color: #28a745;
+ color: #fff !important;
+ background-color: #28a745 !important;
animation: flash 1s infinite;
}
.info-status[status='disabled'] {
--flash-from: #fff;
--flash-to: #e61a05;
- color: #fff;
- background-color: #f89f1b;
+ color: #fff !important;
+ background-color: #f89f1b !important;
animation: flash 3s infinite;
}
.info-status[status='error'] {
--flash-from: #8a8dac;
- color: #fff;
- background-color: #bfadad;
+ color: #fff !important;
+ background-color: #bfadad !important;
}
.info-status::before {
diff --git a/dashboard/src/components/UAChart.vue b/dashboard/src/components/UAChart.vue
index 949fe72f..997b21aa 100644
--- a/dashboard/src/components/UAChart.vue
+++ b/dashboard/src/components/UAChart.vue
@@ -36,13 +36,13 @@ const getChartData = () => {
})
const colors = [
- documentStyle.getPropertyValue('--red-500'),
- documentStyle.getPropertyValue('--orange-500'),
- documentStyle.getPropertyValue('--yellow-500'),
- documentStyle.getPropertyValue('--green-500'),
- documentStyle.getPropertyValue('--cyan-500'),
- documentStyle.getPropertyValue('--blue-500'),
- documentStyle.getPropertyValue('--purple-500'),
+ documentStyle.getPropertyValue('--p-red-500'),
+ documentStyle.getPropertyValue('--p-orange-500'),
+ documentStyle.getPropertyValue('--p-yellow-500'),
+ documentStyle.getPropertyValue('--p-green-500'),
+ documentStyle.getPropertyValue('--p-cyan-500'),
+ documentStyle.getPropertyValue('--p-blue-500'),
+ documentStyle.getPropertyValue('--p-purple-500'),
]
return {
labels: labels,
@@ -60,9 +60,9 @@ const getChartData = () => {
const getChartOptions = () => {
const documentStyle = getComputedStyle(document.documentElement)
- const textColor = documentStyle.getPropertyValue('--text-color')
- const textColorSecondary = documentStyle.getPropertyValue('--text-color-secondary')
- const surfaceBorder = documentStyle.getPropertyValue('--surface-border')
+ const textColor = documentStyle.getPropertyValue('--p-text-color')
+ const textColorSecondary = documentStyle.getPropertyValue('--p-text-color-secondary')
+ const surfaceBorder = documentStyle.getPropertyValue('--p-surface-border')
return {
indexAxis: 'y',
diff --git a/dashboard/src/lang/index.ts b/dashboard/src/lang/index.ts
index 62c372fb..fc65d01b 100644
--- a/dashboard/src/lang/index.ts
+++ b/dashboard/src/lang/index.ts
@@ -77,7 +77,6 @@ export function setLang(lang: Lang | string): Lang | null {
}
export function tr(key: string, ...values: unknown[]): string {
- // console.debug('translating:', key)
const item = currentLang.value
let cur: string | LangMap | null = currentTr.value
if (!cur || (key && typeof cur === 'string')) {
@@ -98,8 +97,12 @@ export function tr(key: string, ...values: unknown[]): string {
if (typeof cur !== 'string') {
return `{{${key}}}`
}
- // TODO: apply values
- return cur
+ return cur.replace(/(\\)?({(0|[1-9][0-9]+)})/g, (raw, escape, slotRaw, n) => {
+ if (escape) {
+ return slotRaw
+ }
+ return values[parseInt(n)]
+ })
}
export const langNameMap: { [key: string]: string } = {
diff --git a/dashboard/src/main.ts b/dashboard/src/main.ts
index 3e1b9993..3f419b1e 100644
--- a/dashboard/src/main.ts
+++ b/dashboard/src/main.ts
@@ -1,8 +1,10 @@
import { createApp, ref, watch, inject, type Ref } from 'vue'
import vueCookies, { type VueCookies } from 'vue-cookies'
import PrimeVue from 'primevue/config'
+import ConfirmationService from 'primevue/confirmationservice'
import FocusTrap from 'primevue/focustrap'
import ToastService from 'primevue/toastservice'
+import Lara from '@primeuix/themes/lara'
import { registerSW } from 'virtual:pwa-register'
import App from './App.vue'
import router from './router'
@@ -10,7 +12,6 @@ import { useCookies, bindRefToCookie } from './cookies'
import './utils/chart'
import { ping } from '@/api/v0'
-import './assets/theme.css'
import 'primeicons/primeicons.css'
import './assets/main.css'
@@ -32,7 +33,17 @@ const app = createApp(App)
app.use(router)
app.use(vueCookies, { expires: '30d', path: import.meta.env.BASE_URL })
-app.use(PrimeVue, { ripple: true })
+app.use(PrimeVue, {
+ ripple: true,
+ theme: {
+ preset: Lara,
+ options: {
+ prefix: 'p',
+ darkModeSelector: 'system',
+ },
+ },
+})
+app.use(ConfirmationService)
app.use(ToastService)
app.directive('focustrap', FocusTrap)
diff --git a/dashboard/src/router/index.ts b/dashboard/src/router/index.ts
index e4f3e096..fb3788fc 100644
--- a/dashboard/src/router/index.ts
+++ b/dashboard/src/router/index.ts
@@ -23,10 +23,11 @@ const router = createRouter({
component: () => import('@/views/LoginView.vue'),
props: (route) => ({ next: route.query.next }),
},
+
{
path: '/settings',
name: 'settings',
- component: () => import('@/views/SettingsView.vue'),
+ component: () => import('@/views/settings/SettingsView.vue'),
},
{
path: '/loglist',
@@ -38,6 +39,17 @@ const router = createRouter({
name: 'settings/notifications',
component: () => import('@/views/settings/NotificationsView.vue'),
},
+
+ {
+ path: '/configure',
+ name: 'configure',
+ component: () => import('@/views/configure/ConfigureView.vue'),
+ },
+ {
+ path: '/configure/clusters',
+ name: 'configure/clusters',
+ component: () => import('@/views/configure/ClustersView.vue'),
+ },
],
scrollBehavior(to, from, savedPosition) {
return savedPosition || { top: 0 }
diff --git a/dashboard/src/views/HomeView.vue b/dashboard/src/views/HomeView.vue
index 4c174ad7..e677f616 100644
--- a/dashboard/src/views/HomeView.vue
+++ b/dashboard/src/views/HomeView.vue
@@ -1,5 +1,5 @@
@@ -266,8 +270,8 @@ onMounted(() => {
{
}
.charts-tab {
- border: 1px solid var(--surface-border);
- border-radius: var(--border-radius);
+ border: 1px solid var(--p-content-border-color);
+ border-radius: var(--p-content-border-radius);
}
.charts-tab-charts {
diff --git a/dashboard/src/views/configure/ClustersView.vue b/dashboard/src/views/configure/ClustersView.vue
new file mode 100644
index 00000000..45172031
--- /dev/null
+++ b/dashboard/src/views/configure/ClustersView.vue
@@ -0,0 +1,460 @@
+
+
+
+
+
+
+
+
+
+ {{ name }}
+ *
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.cluster.id') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.cluster.server') }}
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.cluster.storages') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard/src/views/configure/ConfigureView.vue b/dashboard/src/views/configure/ConfigureView.vue
new file mode 100644
index 00000000..1473f116
--- /dev/null
+++ b/dashboard/src/views/configure/ConfigureView.vue
@@ -0,0 +1,808 @@
+
+
+
+
+
+
+
+ {{ tr('message.settings.login.first') }}
+
+
+
+ Loading ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.public_host') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.public_port') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.host') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.port') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.sync_interval') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.download_max_conn') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.max_reconnect_count') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.log_slots') }}
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.access_log_slots') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ storage.id }}
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.type') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.weight') }}
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.cache_path') }}
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.path') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.redirect_base') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.max_conn') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.max_upload_rate') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.max_download_rate') }}
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.storage.redirect_link_cache') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.tunneler.tunnel_program') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.tunneler.output_regex') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.cache.type') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.serve_limit.max_conn') }}
+
+
+
+
+
+
+
+
+ {{ tr('description.configures.item.serve_limit.upload_rate') }}
+
+
+
+
+
+
+
+
diff --git a/dashboard/src/views/SettingsView.vue b/dashboard/src/views/settings/SettingsView.vue
similarity index 88%
rename from dashboard/src/views/SettingsView.vue
rename to dashboard/src/views/settings/SettingsView.vue
index 52cc494c..cdaa6b84 100644
--- a/dashboard/src/views/SettingsView.vue
+++ b/dashboard/src/views/settings/SettingsView.vue
@@ -1,11 +1,11 @@