瀏覽代碼

enhance: update gonginx and cosy to latest version

0xJacky 1 年之前
父節點
當前提交
85da74b3f0

+ 32 - 21
api/cosy/cosy.go

@@ -14,34 +14,45 @@ func init() {
 }
 
 type Ctx[T any] struct {
-	ctx                   *gin.Context
-	rules                 gin.H
-	Payload               map[string]interface{}
-	Model                 T
-	abort                 bool
-	nextHandler           *gin.HandlerFunc
-	beforeDecodeHookFunc  []func(ctx *Ctx[T])
-	beforeExecuteHookFunc []func(ctx *Ctx[T])
-	executedHookFunc      []func(ctx *Ctx[T])
-	gormScopes            []func(tx *gorm.DB) *gorm.DB
-	preloads              []string
-	scan                  func(tx *gorm.DB) any
-	transformer           func(*T) any
-	permanentlyDelete     bool
-	SelectedFields        []string
-	itemKey               string
+	ctx                      *gin.Context
+	rules                    gin.H
+	Payload                  map[string]interface{}
+	Model                    T
+	OriginModel              T
+	table                    string
+	tableArgs                []interface{}
+	abort                    bool
+	nextHandler              *gin.HandlerFunc
+	skipAssociationsOnCreate bool
+	beforeDecodeHookFunc     []func(ctx *Ctx[T])
+	beforeExecuteHookFunc    []func(ctx *Ctx[T])
+	executedHookFunc         []func(ctx *Ctx[T])
+	gormScopes               []func(tx *gorm.DB) *gorm.DB
+	preloads                 []string
+	scan                     func(tx *gorm.DB) any
+	transformer              func(*T) any
+	permanentlyDelete        bool
+	SelectedFields           []string
+	itemKey                  string
 }
 
 func Core[T any](c *gin.Context) *Ctx[T] {
 	return &Ctx[T]{
-		ctx:                   c,
-		gormScopes:            make([]func(tx *gorm.DB) *gorm.DB, 0),
-		beforeExecuteHookFunc: make([]func(ctx *Ctx[T]), 0),
-		beforeDecodeHookFunc:  make([]func(ctx *Ctx[T]), 0),
-		itemKey:               "`id`",
+		ctx:                      c,
+		gormScopes:               make([]func(tx *gorm.DB) *gorm.DB, 0),
+		beforeExecuteHookFunc:    make([]func(ctx *Ctx[T]), 0),
+		beforeDecodeHookFunc:     make([]func(ctx *Ctx[T]), 0),
+		itemKey:                  "`id`",
+		skipAssociationsOnCreate: true,
 	}
 }
 
+func (c *Ctx[T]) SetTable(table string, args ...interface{}) *Ctx[T] {
+	c.table = table
+	c.tableArgs = args
+	return c
+}
+
 func (c *Ctx[T]) SetItemKey(key string) *Ctx[T] {
 	c.itemKey = key
 	return c

+ 12 - 4
api/cosy/create.go

@@ -1,9 +1,9 @@
 package cosy
 
 import (
+	"github.com/gin-gonic/gin"
 	"github.com/0xJacky/Nginx-UI/api/cosy/map2struct"
 	"github.com/0xJacky/Nginx-UI/model"
-	"github.com/gin-gonic/gin"
 	"gorm.io/gorm/clause"
 	"net/http"
 )
@@ -41,8 +41,11 @@ func (c *Ctx[T]) Create() {
 		return
 	}
 
-	// skip all associations
-	err = db.Omit(clause.Associations).Create(&c.Model).Error
+	if c.skipAssociationsOnCreate {
+		err = db.Omit(clause.Associations).Create(&c.Model).Error
+	} else {
+		err = db.Create(&c.Model).Error
+	}
 
 	if err != nil {
 		errHandler(c.ctx, err)
@@ -53,7 +56,7 @@ func (c *Ctx[T]) Create() {
 	for _, v := range c.preloads {
 		tx = tx.Preload(v)
 	}
-	tx.First(&c.Model)
+	tx.Table(c.table, c.tableArgs...).First(&c.Model)
 
 	if len(c.executedHookFunc) > 0 {
 		for _, v := range c.executedHookFunc {
@@ -70,3 +73,8 @@ func (c *Ctx[T]) Create() {
 		c.ctx.JSON(http.StatusOK, c.Model)
 	}
 }
+
+func (c *Ctx[T]) WithAssociations() *Ctx[T] {
+	c.skipAssociationsOnCreate = false
+	return c
+}

+ 1 - 1
api/cosy/custom.go

@@ -1,8 +1,8 @@
 package cosy
 
 import (
-	"github.com/0xJacky/Nginx-UI/api/cosy/map2struct"
 	"github.com/gin-gonic/gin"
+	"github.com/0xJacky/Nginx-UI/api/cosy/map2struct"
 	"net/http"
 )
 

+ 14 - 2
api/cosy/delete.go

@@ -27,7 +27,13 @@ func (c *Ctx[T]) Destroy() {
 		result = result.Scopes(c.gormScopes...)
 	}
 
-	err := result.Session(&gorm.Session{}).First(&dbModel, id).Error
+	var err error
+	session := result.Session(&gorm.Session{})
+	if c.table != "" {
+		err = session.Table(c.table, c.tableArgs...).Take(&dbModel, id).Error
+	} else {
+		err = session.First(&dbModel, id).Error
+	}
 
 	if err != nil {
 		errHandler(c.ctx, err)
@@ -73,7 +79,13 @@ func (c *Ctx[T]) Recover() {
 		result = result.Scopes(c.gormScopes...)
 	}
 
-	err := result.Session(&gorm.Session{}).First(&dbModel, id).Error
+	var err error
+	session := result.Session(&gorm.Session{})
+	if c.table != "" {
+		err = session.Table(c.table).Take(&dbModel, id).Error
+	} else {
+		err = session.First(&dbModel, id).Error
+	}
 
 	if err != nil {
 		errHandler(c.ctx, err)

+ 1 - 1
api/cosy/error.go

@@ -2,8 +2,8 @@ package cosy
 
 import (
 	"errors"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/gin-gonic/gin"
+	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"go.uber.org/zap"
 	"gorm.io/gorm"
 	"net/http"

+ 15 - 10
api/cosy/filter.go

@@ -2,9 +2,10 @@ package cosy
 
 import (
 	"fmt"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/gin-gonic/gin"
+	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"gorm.io/gorm"
+	"gorm.io/gorm/clause"
 	"strings"
 )
 
@@ -63,16 +64,17 @@ func QueryToInSearch(c *gin.Context, db *gorm.DB, keys ...string) *gorm.DB {
 		if len(queryArray) == 0 {
 			queryArray = c.QueryArray(v)
 		}
-		if len(queryArray) > 0 {
-			var sb strings.Builder
+		if len(queryArray) == 1 && queryArray[0] == "" {
+			continue
+		}
+		if len(queryArray) >= 1 {
+			var builder strings.Builder
+			stmt := db.Statement
 
-			_, err := fmt.Fprintf(&sb, "`%s` IN ?", v)
-			if err != nil {
-				logger.Error(err)
-				continue
-			}
+			stmt.QuoteTo(&builder, clause.Column{Table: stmt.Table, Name: v})
+			builder.WriteString(" IN ?")
 
-			db = db.Where(sb.String(), queryArray)
+			db = db.Where(builder.String(), queryArray)
 		}
 	}
 	return db
@@ -148,7 +150,10 @@ func QueryToOrInSearch(c *gin.Context, db *gorm.DB, keys ...string) *gorm.DB {
 		if len(queryArray) == 0 {
 			queryArray = c.QueryArray(v)
 		}
-		if len(queryArray) > 0 {
+		if len(queryArray) == 1 && queryArray[0] == "" {
+			continue
+		}
+		if len(queryArray) >= 1 {
 			var sb strings.Builder
 
 			_, err := fmt.Fprintf(&sb, "`%s` IN ?", v)

+ 42 - 16
api/cosy/list.go

@@ -25,14 +25,11 @@ func GetPagingParams(c *gin.Context) (page, offset, pageSize int) {
 }
 
 func (c *Ctx[T]) combineStdSelectorRequest() {
-	var StdSelectorInitParams struct {
-		ID []int `json:"id"`
-	}
+	StdSelectorInitID := c.ctx.QueryArray("id[]")
 
-	_ = c.ctx.ShouldBindJSON(&StdSelectorInitParams)
-	if len(StdSelectorInitParams.ID) > 0 {
+	if len(StdSelectorInitID) > 0 {
 		c.GormScope(func(tx *gorm.DB) *gorm.DB {
-			return tx.Where(c.itemKey+" IN ?", StdSelectorInitParams.ID)
+			return tx.Where(c.itemKey+" IN ?", StdSelectorInitID)
 		})
 	}
 }
@@ -62,6 +59,9 @@ func (c *Ctx[T]) result() (*gorm.DB, bool) {
 	}
 
 	result = result.Model(&dbModel)
+	if c.table != "" {
+		result = result.Table(c.table, c.tableArgs...)
+	}
 
 	c.combineStdSelectorRequest()
 
@@ -72,16 +72,30 @@ func (c *Ctx[T]) result() (*gorm.DB, bool) {
 	return result, true
 }
 
-func (c *Ctx[T]) ListAllData() ([]*T, bool) {
+func (c *Ctx[T]) ListAllData() (data any, ok bool) {
 	result, ok := c.result()
 	if !ok {
 		return nil, false
 	}
 
 	result = result.Scopes(c.SortOrder())
-	models := make([]*T, 0)
-	result.Find(&models)
-	return models, true
+	if c.scan == nil {
+		models := make([]*T, 0)
+		result.Find(&models)
+
+		if c.transformer != nil {
+			transformed := make([]any, 0)
+			for k := range models {
+				transformed = append(transformed, c.transformer(models[k]))
+			}
+			data = transformed
+		} else {
+			data = models
+		}
+	} else {
+		data = c.scan(result)
+	}
+	return data, true
 }
 
 func (c *Ctx[T]) PagingListData() (*model.DataList, bool) {
@@ -90,11 +104,11 @@ func (c *Ctx[T]) PagingListData() (*model.DataList, bool) {
 		return nil, false
 	}
 
-	result = result.Scopes(c.OrderAndPaginate())
+	scopesResult := result.Session(&gorm.Session{}).Scopes(c.OrderAndPaginate())
 	data := &model.DataList{}
 	if c.scan == nil {
 		models := make([]*T, 0)
-		result.Find(&models)
+		scopesResult.Find(&models)
 
 		if c.transformer != nil {
 			transformed := make([]any, 0)
@@ -106,9 +120,12 @@ func (c *Ctx[T]) PagingListData() (*model.DataList, bool) {
 			data.Data = models
 		}
 	} else {
-		data.Data = c.scan(result)
+		data.Data = c.scan(scopesResult)
 	}
 
+	var totalRecords int64
+	result.Session(&gorm.Session{}).Count(&totalRecords)
+
 	page := cast.ToInt(c.ctx.Query("page"))
 	if page == 0 {
 		page = 1
@@ -119,9 +136,6 @@ func (c *Ctx[T]) PagingListData() (*model.DataList, bool) {
 		pageSize = cast.ToInt(reqPageSize)
 	}
 
-	var totalRecords int64
-	result.Session(&gorm.Session{}).Count(&totalRecords)
-
 	data.Pagination = model.Pagination{
 		Total:       totalRecords,
 		PerPage:     pageSize,
@@ -137,3 +151,15 @@ func (c *Ctx[T]) PagingList() {
 		c.ctx.JSON(http.StatusOK, data)
 	}
 }
+
+// EmptyPagingList return empty list
+func (c *Ctx[T]) EmptyPagingList() {
+	pageSize := settings.ServerSettings.PageSize
+	if reqPageSize := c.ctx.Query("page_size"); reqPageSize != "" {
+		pageSize = cast.ToInt(reqPageSize)
+	}
+
+	data := &model.DataList{Data: make([]any, 0)}
+	data.Pagination.PerPage = pageSize
+	c.ctx.JSON(http.StatusOK, data)
+}

+ 12 - 1
api/cosy/map2struct/hook.go

@@ -4,6 +4,7 @@ import (
 	"github.com/mitchellh/mapstructure"
 	"github.com/shopspring/decimal"
 	"github.com/spf13/cast"
+	"gopkg.in/guregu/null.v4"
 	"reflect"
 	"time"
 )
@@ -11,7 +12,7 @@ import (
 var timeLocation *time.Location
 
 func init() {
-	timeLocation = time.Local
+	timeLocation, _ = time.LoadLocation("Asia/Shanghai")
 }
 
 func ToTimeHookFunc() mapstructure.DecodeHookFunc {
@@ -54,3 +55,13 @@ func ToDecimalHookFunc() mapstructure.DecodeHookFunc {
 		return data, nil
 	}
 }
+
+func ToNullableStringHookFunc() mapstructure.DecodeHookFunc {
+	return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+		if t == reflect.TypeOf(null.String{}) {
+			return null.StringFrom(data.(string)), nil
+		}
+
+		return data, nil
+	}
+}

+ 1 - 1
api/cosy/map2struct/map2struct.go

@@ -10,7 +10,7 @@ func WeakDecode(input, output interface{}) error {
 		Result:           output,
 		WeaklyTypedInput: true,
 		DecodeHook: mapstructure.ComposeDecodeHookFunc(
-			ToDecimalHookFunc(), ToTimeHookFunc(),
+			ToDecimalHookFunc(), ToTimeHookFunc(), ToNullableStringHookFunc(),
 		),
 		TagName: "json",
 	}

+ 4 - 0
api/cosy/order.go

@@ -22,6 +22,10 @@ func (c *Ctx[T]) UpdateOrder() {
 
 	db := model.UseDB()
 
+	if c.table != "" {
+		db = db.Table(c.table, c.tableArgs...)
+	}
+
 	// update target
 	err := db.Model(&c.Model).Where("id = ?", json.TargetID).Update("order_id", gorm.Expr("order_id + ?", affectedLen*(-json.Direction))).Error
 

+ 14 - 22
api/cosy/sort.go

@@ -3,7 +3,6 @@ package cosy
 import (
 	"fmt"
 	"github.com/0xJacky/Nginx-UI/internal/logger"
-	"github.com/gin-gonic/gin"
 	"gorm.io/gorm"
 	"gorm.io/gorm/schema"
 	"sync"
@@ -16,18 +15,22 @@ func (c *Ctx[T]) SortOrder() func(db *gorm.DB) *gorm.DB {
 			sort = "desc"
 		}
 
-		// check if the order field is valid
-		// todo: maybe we can use more generic way to check if the sort_by is valid
-		order := DefaultQuery(c.ctx, "sort_by", c.itemKey)
-		s, _ := schema.Parse(c.Model, &sync.Map{}, schema.NamingStrategy{})
-		if _, ok := s.FieldsByDBName[order]; ok {
-			order = fmt.Sprintf("%s %s", order, sort)
-			return db.Order(order)
-		} else {
-			logger.Error("invalid order field:", order)
+		order := c.itemKey
+		if value, ok := c.ctx.Get("order"); ok {
+			// check if the order field is valid
+			// todo: maybe we can use more generic way to check if the sort_by is valid
+			s, _ := schema.Parse(c.Model, &sync.Map{}, schema.NamingStrategy{})
+			if _, ok := s.FieldsByDBName[value.(string)]; ok {
+				order = value.(string)
+			} else {
+				logger.Error("invalid order field:", order)
+			}
+		} else if value, ok := c.ctx.Get("sort_by"); ok {
+			order = value.(string)
 		}
 
-		return db
+		order = fmt.Sprintf("%s %s", order, sort)
+		return db.Order(order)
 	}
 }
 
@@ -38,14 +41,3 @@ func (c *Ctx[T]) OrderAndPaginate() func(db *gorm.DB) *gorm.DB {
 		return db.Offset(offset).Limit(pageSize)
 	}
 }
-
-func DefaultValue(c *gin.Context, key string, defaultValue any) any {
-	if value, ok := c.Get(key); ok {
-		return value
-	}
-	return defaultValue
-}
-
-func DefaultQuery(c *gin.Context, key string, defaultValue any) string {
-	return c.DefaultQuery(key, DefaultValue(c, key, defaultValue).(string))
-}

+ 8 - 7
api/cosy/update.go

@@ -5,8 +5,8 @@ import (
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/gin-gonic/gin"
 	"gorm.io/gorm"
-    "gorm.io/gorm/clause"
-    "net/http"
+	"gorm.io/gorm/clause"
+	"net/http"
 )
 
 func (c *Ctx[T]) SetNextHandler(handler gin.HandlerFunc) *Ctx[T] {
@@ -29,8 +29,6 @@ func (c *Ctx[T]) Modify() {
 		return
 	}
 
-	var dbModel T
-
 	db := model.UseDB()
 
 	result := db
@@ -38,7 +36,7 @@ func (c *Ctx[T]) Modify() {
 		result = result.Scopes(c.gormScopes...)
 	}
 
-	err := result.Session(&gorm.Session{}).First(&dbModel, id).Error
+	err := result.Session(&gorm.Session{}).First(&c.OriginModel, id).Error
 
 	if err != nil {
 		c.AbortWithError(err)
@@ -68,7 +66,10 @@ func (c *Ctx[T]) Modify() {
 		return
 	}
 
-	err = db.Model(&dbModel).Select(selectedFields).Updates(&c.Model).Error
+	if c.table != "" {
+		db = db.Table(c.table, c.tableArgs...)
+	}
+	err = db.Model(&c.OriginModel).Select(selectedFields).Updates(&c.Model).Error
 
 	if err != nil {
 		c.AbortWithError(err)
@@ -95,6 +96,6 @@ func (c *Ctx[T]) Modify() {
 	if c.nextHandler != nil {
 		(*c.nextHandler)(c.ctx)
 	} else {
-		c.ctx.JSON(http.StatusOK, dbModel)
+		c.ctx.JSON(http.StatusOK, c.Model)
 	}
 }

+ 17 - 8
api/nginx/nginx.go

@@ -13,9 +13,13 @@ func BuildNginxConfig(c *gin.Context) {
 	if !api.BindAndValid(c, &ngxConf) {
 		return
 	}
-	c.Set("maybe_error", "nginx_config_syntax_error")
+	content, err := ngxConf.BuildConfig()
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
 	c.JSON(http.StatusOK, gin.H{
-		"content": ngxConf.BuildConfig(),
+		"content": content,
 	})
 }
 
@@ -28,9 +32,11 @@ func TokenizeNginxConfig(c *gin.Context) {
 		return
 	}
 
-	c.Set("maybe_error", "nginx_config_syntax_error")
-	ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
-
+	ngxConfig, err := nginx.ParseNgxConfigByContent(json.Content)
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
 	c.JSON(http.StatusOK, ngxConfig)
 
 }
@@ -43,10 +49,13 @@ func FormatNginxConfig(c *gin.Context) {
 	if !api.BindAndValid(c, &json) {
 		return
 	}
-
-	c.Set("maybe_error", "nginx_config_syntax_error")
+	content, err := nginx.FmtCode(json.Content)
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
 	c.JSON(http.StatusOK, gin.H{
-		"content": nginx.FmtCode(json.Content),
+		"content": content,
 	})
 }
 

+ 0 - 6
api/sites/domain.go

@@ -136,7 +136,6 @@ func GetDomain(c *gin.Context) {
 		return
 	}
 
-	c.Set("maybe_error", "nginx_config_syntax_error")
 	nginxConfig, err := nginx.ParseNgxConfig(path)
 
 	if err != nil {
@@ -144,8 +143,6 @@ func GetDomain(c *gin.Context) {
 		return
 	}
 
-	c.Set("maybe_error", "")
-
 	certInfoMap := make(map[int]*cert.Info)
 
 	for serverIdx, server := range nginxConfig.Servers {
@@ -166,8 +163,6 @@ func GetDomain(c *gin.Context) {
 		}
 	}
 
-	c.Set("maybe_error", "nginx_config_syntax_error")
-
 	c.JSON(http.StatusOK, Site{
 		ModifiedAt:      file.ModTime(),
 		Advanced:        site.Advanced,
@@ -259,7 +254,6 @@ func SaveDomain(c *gin.Context) {
 		if nginx.GetLogLevel(output) > nginx.Warn {
 			c.JSON(http.StatusInternalServerError, gin.H{
 				"message": output,
-				"error":   "nginx_config_syntax_error",
 			})
 			return
 		}

+ 0 - 2
api/streams/streams.go

@@ -137,7 +137,6 @@ func GetStream(c *gin.Context) {
 		return
 	}
 
-	c.Set("maybe_error", "nginx_config_syntax_error")
 	nginxConfig, err := nginx.ParseNgxConfig(path)
 
 	if err != nil {
@@ -234,7 +233,6 @@ func SaveStream(c *gin.Context) {
 		if nginx.GetLogLevel(output) > nginx.Warn {
 			c.JSON(http.StatusInternalServerError, gin.H{
 				"message": output,
-				"error":   "nginx_config_syntax_error",
 			})
 			return
 		}

+ 7 - 1
api/template/template.go

@@ -38,9 +38,15 @@ func GetTemplate(c *gin.Context) {
 		},
 	}
 
+	content, err := ngxConfig.BuildConfig()
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
+
 	c.JSON(http.StatusOK, gin.H{
 		"message":   "ok",
-		"template":  ngxConfig.BuildConfig(),
+		"template":  content,
 		"tokenized": ngxConfig,
 	})
 }

+ 2 - 2
app/package.json

@@ -29,7 +29,7 @@
     "reconnecting-websocket": "^4.4.0",
     "sortablejs": "^1.15.0",
     "vite-plugin-build-id": "^0.2.8",
-    "vue": "^3.3.11",
+    "vue": "^3.4.13",
     "vue-github-button": "https://github.com/0xJacky/vue-github-button",
     "vue-router": "^4.2.5",
     "vue3-ace-editor": "2.2.4",
@@ -67,7 +67,7 @@
     "unplugin-auto-import": "^0.17.1",
     "unplugin-vue-components": "^0.25.2",
     "unplugin-vue-define-options": "^1.4.0",
-    "vite": "^5.0.9",
+    "vite": "^5.0.11",
     "vite-svg-loader": "^5.1.0",
     "vue-tsc": "^1.8.22"
   }

+ 140 - 107
app/pnpm-lock.yaml

@@ -7,7 +7,7 @@ settings:
 dependencies:
   '@ant-design/icons-vue':
     specifier: ^7.0.1
-    version: 7.0.1(vue@3.3.11)
+    version: 7.0.1(vue@3.4.13)
   '@formkit/auto-animate':
     specifier: ^0.8.0
     version: 0.8.1
@@ -19,10 +19,10 @@ dependencies:
     version: 3.3.10
   '@vueuse/core':
     specifier: ^10.6.1
-    version: 10.6.1(vue@3.3.11)
+    version: 10.6.1(vue@3.4.13)
   ant-design-vue:
     specifier: 4.0.8
-    version: 4.0.8(vue@3.3.11)
+    version: 4.0.8(vue@3.4.13)
   apexcharts:
     specifier: ^3.36.3
     version: 3.44.0
@@ -46,7 +46,7 @@ dependencies:
     version: 0.2.0
   pinia:
     specifier: ^2.1.7
-    version: 2.1.7(typescript@5.3.2)(vue@3.3.11)
+    version: 2.1.7(typescript@5.3.2)(vue@3.4.13)
   pinia-plugin-persistedstate:
     specifier: ^3.0.2
     version: 3.2.0(pinia@2.1.7)
@@ -60,26 +60,26 @@ dependencies:
     specifier: ^0.2.8
     version: 0.2.8(less@4.2.0)
   vue:
-    specifier: ^3.3.11
-    version: 3.3.11(typescript@5.3.2)
+    specifier: ^3.4.13
+    version: 3.4.13(typescript@5.3.2)
   vue-github-button:
     specifier: https://github.com/0xJacky/vue-github-button
     version: github.com/0xJacky/vue-github-button/fc3c93355a790d3249de6610de3ebe35949ee314
   vue-router:
     specifier: ^4.2.5
-    version: 4.2.5(vue@3.3.11)
+    version: 4.2.5(vue@3.4.13)
   vue3-ace-editor:
     specifier: 2.2.4
-    version: 2.2.4(ace-builds@1.32.0)(vue@3.3.11)
+    version: 2.2.4(ace-builds@1.32.0)(vue@3.4.13)
   vue3-apexcharts:
     specifier: ^1.4.4
-    version: 1.4.4(apexcharts@3.44.0)(vue@3.3.11)
+    version: 1.4.4(apexcharts@3.44.0)(vue@3.4.13)
   vue3-gettext:
     specifier: ^3.0.0-beta.3
-    version: 3.0.0-beta.3(@vue/compiler-sfc@3.3.10)(vue@3.3.11)
+    version: 3.0.0-beta.3(@vue/compiler-sfc@3.3.10)(vue@3.4.13)
   vuedraggable:
     specifier: ^4.1.0
-    version: 4.1.0(vue@3.3.11)
+    version: 4.1.0(vue@3.4.13)
   xterm:
     specifier: ^5.3.0
     version: 5.3.0
@@ -111,10 +111,10 @@ devDependencies:
     version: 6.13.1(eslint@8.56.0)(typescript@5.3.2)
   '@vitejs/plugin-vue':
     specifier: ^4.5.0
-    version: 4.5.1(vite@5.0.9)(vue@3.3.11)
+    version: 4.5.1(vite@5.0.11)(vue@3.4.13)
   '@vitejs/plugin-vue-jsx':
     specifier: ^3.1.0
-    version: 3.1.0(vite@5.0.9)(vue@3.3.11)
+    version: 3.1.0(vite@5.0.11)(vue@3.4.13)
   '@vue/compiler-sfc':
     specifier: ^3.3.10
     version: 3.3.10
@@ -165,16 +165,16 @@ devDependencies:
     version: 0.17.1(@vueuse/core@10.6.1)
   unplugin-vue-components:
     specifier: ^0.25.2
-    version: 0.25.2(vue@3.3.11)
+    version: 0.25.2(vue@3.4.13)
   unplugin-vue-define-options:
     specifier: ^1.4.0
-    version: 1.4.0(vue@3.3.11)
+    version: 1.4.0(vue@3.4.13)
   vite:
-    specifier: ^5.0.9
-    version: 5.0.9(@types/node@20.10.2)(less@4.2.0)
+    specifier: ^5.0.11
+    version: 5.0.11(@types/node@20.10.2)(less@4.2.0)
   vite-svg-loader:
     specifier: ^5.1.0
-    version: 5.1.0(vue@3.3.11)
+    version: 5.1.0(vue@3.4.13)
   vue-tsc:
     specifier: ^1.8.22
     version: 1.8.24(typescript@5.3.2)
@@ -209,14 +209,14 @@ packages:
     resolution: {integrity: sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==}
     dev: false
 
-  /@ant-design/icons-vue@7.0.1(vue@3.3.11):
+  /@ant-design/icons-vue@7.0.1(vue@3.4.13):
     resolution: {integrity: sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==}
     peerDependencies:
       vue: '>=3.0.3'
     dependencies:
       '@ant-design/colors': 6.0.0
       '@ant-design/icons-svg': 4.3.1
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
   /@antfu/eslint-config-basic@0.43.1(@typescript-eslint/eslint-plugin@6.13.1)(@typescript-eslint/parser@6.13.1)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0)(typescript@5.3.2):
@@ -507,6 +507,13 @@ packages:
     dependencies:
       '@babel/types': 7.23.5
 
+  /@babel/parser@7.23.6:
+    resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.23.5
+
   /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.5):
     resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
     engines: {node: '>=6.9.0'}
@@ -1314,7 +1321,7 @@ packages:
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
     dev: true
 
-  /@vitejs/plugin-vue-jsx@3.1.0(vite@5.0.9)(vue@3.3.11):
+  /@vitejs/plugin-vue-jsx@3.1.0(vite@5.0.11)(vue@3.4.13):
     resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
@@ -1324,21 +1331,21 @@ packages:
       '@babel/core': 7.23.5
       '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.23.5)
       '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.5)
-      vite: 5.0.9(@types/node@20.10.2)(less@4.2.0)
-      vue: 3.3.11(typescript@5.3.2)
+      vite: 5.0.11(@types/node@20.10.2)(less@4.2.0)
+      vue: 3.4.13(typescript@5.3.2)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@vitejs/plugin-vue@4.5.1(vite@5.0.9)(vue@3.3.11):
+  /@vitejs/plugin-vue@4.5.1(vite@5.0.11)(vue@3.4.13):
     resolution: {integrity: sha512-DaUzYFr+2UGDG7VSSdShKa9sIWYBa1LL8KC0MNOf2H5LjcTPjob0x8LbkqXWmAtbANJCkpiQTj66UVcQkN2s3g==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       vite: ^4.0.0 || ^5.0.0
       vue: ^3.2.25
     dependencies:
-      vite: 5.0.9(@types/node@20.10.2)(less@4.2.0)
-      vue: 3.3.11(typescript@5.3.2)
+      vite: 5.0.11(@types/node@20.10.2)(less@4.2.0)
+      vue: 3.4.13(typescript@5.3.2)
     dev: true
 
   /@volar/language-core@1.11.1:
@@ -1360,7 +1367,7 @@ packages:
       path-browserify: 1.0.1
     dev: true
 
-  /@vue-macros/common@1.9.0(vue@3.3.11):
+  /@vue-macros/common@1.9.0(vue@3.4.13):
     resolution: {integrity: sha512-LbfRHDkceuokkLlVuQW9Wq3ZLmRs6KIDPzCjUvvL14HB4GslWdtvBB1suFfNs6VMvh9Zj30cEKF/EAP7QBCZ6Q==}
     engines: {node: '>=16.14.0'}
     peerDependencies:
@@ -1371,11 +1378,11 @@ packages:
     dependencies:
       '@babel/types': 7.23.5
       '@rollup/pluginutils': 5.1.0
-      '@vue/compiler-sfc': 3.3.10
+      '@vue/compiler-sfc': 3.3.11
       ast-kit: 0.11.2
       local-pkg: 0.5.0
       magic-string-ast: 0.3.0
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     transitivePeerDependencies:
       - rollup
     dev: true
@@ -1418,15 +1425,16 @@ packages:
       '@vue/shared': 3.3.11
       estree-walker: 2.0.2
       source-map-js: 1.0.2
+    dev: true
 
-  /@vue/compiler-core@3.3.9:
-    resolution: {integrity: sha512-+/Lf68Vr/nFBA6ol4xOtJrW+BQWv3QWKfRwGSm70jtXwfhZNF4R/eRgyVJYoxFRhdCTk/F6g99BP0ffPgZihfQ==}
+  /@vue/compiler-core@3.4.13:
+    resolution: {integrity: sha512-zGUdmB3j3Irn9z51GXLJ5s0EAHxmsm5/eXl0y6MBaajMeOAaiT4+zaDoxui4Ets98dwIRr8BBaqXXHtHSfm+KA==}
     dependencies:
-      '@babel/parser': 7.23.5
-      '@vue/shared': 3.3.9
+      '@babel/parser': 7.23.6
+      '@vue/shared': 3.4.13
+      entities: 4.5.0
       estree-walker: 2.0.2
       source-map-js: 1.0.2
-    dev: true
 
   /@vue/compiler-dom@3.3.10:
     resolution: {integrity: sha512-NCrqF5fm10GXZIK0GrEAauBqdy+F2LZRt3yNHzrYjpYBuRssQbuPLtSnSNjyR9luHKkWSH8we5LMB3g+4z2HvA==}
@@ -1439,13 +1447,13 @@ packages:
     dependencies:
       '@vue/compiler-core': 3.3.11
       '@vue/shared': 3.3.11
+    dev: true
 
-  /@vue/compiler-dom@3.3.9:
-    resolution: {integrity: sha512-nfWubTtLXuT4iBeDSZ5J3m218MjOy42Vp2pmKVuBKo2/BLcrFUX8nCSr/bKRFiJ32R8qbdnnnBgRn9AdU5v0Sg==}
+  /@vue/compiler-dom@3.4.13:
+    resolution: {integrity: sha512-XSNbpr5Rs3kCfVAmBqMu/HDwOS+RL6y28ZZjDlnDUuf146pRWt2sQkwhsOYc9uu2lxjjJy2NcyOkK7MBLVEc7w==}
     dependencies:
-      '@vue/compiler-core': 3.3.9
-      '@vue/shared': 3.3.9
-    dev: true
+      '@vue/compiler-core': 3.4.13
+      '@vue/shared': 3.4.13
 
   /@vue/compiler-sfc@3.3.10:
     resolution: {integrity: sha512-xpcTe7Rw7QefOTRFFTlcfzozccvjM40dT45JtrE3onGm/jBLZ0JhpKu3jkV7rbDFLeeagR/5RlJ2Y9SvyS0lAg==}
@@ -1474,6 +1482,20 @@ packages:
       magic-string: 0.30.5
       postcss: 8.4.32
       source-map-js: 1.0.2
+    dev: true
+
+  /@vue/compiler-sfc@3.4.13:
+    resolution: {integrity: sha512-SkpmQN8xIFBd5onT413DFSDdjxULJf6jmJg/t3w/DZ9I8ZzyNlLIBLO0qFLewVHyHCiAgpPZlWqSRZXYrawk3Q==}
+    dependencies:
+      '@babel/parser': 7.23.6
+      '@vue/compiler-core': 3.4.13
+      '@vue/compiler-dom': 3.4.13
+      '@vue/compiler-ssr': 3.4.13
+      '@vue/shared': 3.4.13
+      estree-walker: 2.0.2
+      magic-string: 0.30.5
+      postcss: 8.4.32
+      source-map-js: 1.0.2
 
   /@vue/compiler-ssr@3.3.10:
     resolution: {integrity: sha512-12iM4jA4GEbskwXMmPcskK5wImc2ohKm408+o9iox3tfN9qua8xL0THIZtoe9OJHnXP4eOWZpgCAAThEveNlqQ==}
@@ -1486,6 +1508,13 @@ packages:
     dependencies:
       '@vue/compiler-dom': 3.3.11
       '@vue/shared': 3.3.11
+    dev: true
+
+  /@vue/compiler-ssr@3.4.13:
+    resolution: {integrity: sha512-rwnw9SVBgD6eGKh8UucnwztieQo/R3RQrEGpE0b0cxb2xxvJeLs/fe7DoYlhEfaSyzM/qD5odkK87hl3G3oW+A==}
+    dependencies:
+      '@vue/compiler-dom': 3.4.13
+      '@vue/shared': 3.4.13
 
   /@vue/devtools-api@6.5.1:
     resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
@@ -1501,8 +1530,8 @@ packages:
     dependencies:
       '@volar/language-core': 1.11.1
       '@volar/source-map': 1.11.1
-      '@vue/compiler-dom': 3.3.9
-      '@vue/shared': 3.3.10
+      '@vue/compiler-dom': 3.3.11
+      '@vue/shared': 3.3.11
       computeds: 0.0.1
       minimatch: 9.0.3
       muggle-string: 0.3.1
@@ -1528,6 +1557,7 @@ packages:
       '@vue/shared': 3.3.11
       estree-walker: 2.0.2
       magic-string: 0.30.5
+    dev: true
 
   /@vue/reactivity@3.3.10:
     resolution: {integrity: sha512-H5Z7rOY/JLO+e5a6/FEXaQ1TMuOvY4LDVgT+/+HKubEAgs9qeeZ+NhADSeEtrNQeiKLDuzeKc8v0CUFpB6Pqgw==}
@@ -1535,54 +1565,54 @@ packages:
       '@vue/shared': 3.3.10
     dev: false
 
-  /@vue/reactivity@3.3.11:
-    resolution: {integrity: sha512-D5tcw091f0nuu+hXq5XANofD0OXnBmaRqMYl5B3fCR+mX+cXJIGNw/VNawBqkjLNWETrFW0i+xH9NvDbTPVh7g==}
+  /@vue/reactivity@3.4.13:
+    resolution: {integrity: sha512-/ZdUOrGKkGVONzVJkfDqNcn2fLMvaa5VlYx2KwTbnRbX06YZ4GJE0PVTmWzIxtBYdpSTLLXgw3pDggO+96KXzg==}
     dependencies:
-      '@vue/shared': 3.3.11
+      '@vue/shared': 3.4.13
 
-  /@vue/runtime-core@3.3.11:
-    resolution: {integrity: sha512-g9ztHGwEbS5RyWaOpXuyIVFTschclnwhqEbdy5AwGhYOgc7m/q3NFwr50MirZwTTzX55JY8pSkeib9BX04NIpw==}
+  /@vue/runtime-core@3.4.13:
+    resolution: {integrity: sha512-Ov4d4At7z3goxqzSqQxdfVYEcN5HY4dM1uDYL6Hu/Es9Za9BEN602zyjWhhi2+BEki5F9NizRSvn02k/tqNWlg==}
     dependencies:
-      '@vue/reactivity': 3.3.11
-      '@vue/shared': 3.3.11
+      '@vue/reactivity': 3.4.13
+      '@vue/shared': 3.4.13
 
-  /@vue/runtime-dom@3.3.11:
-    resolution: {integrity: sha512-OlhtV1PVpbgk+I2zl+Y5rQtDNcCDs12rsRg71XwaA2/Rbllw6mBLMi57VOn8G0AjOJ4Mdb4k56V37+g8ukShpQ==}
+  /@vue/runtime-dom@3.4.13:
+    resolution: {integrity: sha512-ynde9p16eEV3u1VCxUre2e0nKzD0l3NzH0r599+bXeLT1Yhac8Atcot3iL9XNqwolxYCI89KBII+2MSVzfrz6w==}
     dependencies:
-      '@vue/runtime-core': 3.3.11
-      '@vue/shared': 3.3.11
-      csstype: 3.1.2
+      '@vue/runtime-core': 3.4.13
+      '@vue/shared': 3.4.13
+      csstype: 3.1.3
 
-  /@vue/server-renderer@3.3.11(vue@3.3.11):
-    resolution: {integrity: sha512-AIWk0VwwxCAm4wqtJyxBylRTXSy1wCLOKbWxHaHiu14wjsNYtiRCSgVuqEPVuDpErOlRdNnuRgipQfXRLjLN5A==}
+  /@vue/server-renderer@3.4.13(vue@3.4.13):
+    resolution: {integrity: sha512-hkw+UQyDZZtSn1q30nObMfc8beVEQv2pG08nghigxGw+iOWodR+tWSuJak0mzWAHlP/xt/qLc//dG6igfgvGEA==}
     peerDependencies:
-      vue: 3.3.11
+      vue: 3.4.13
     dependencies:
-      '@vue/compiler-ssr': 3.3.11
-      '@vue/shared': 3.3.11
-      vue: 3.3.11(typescript@5.3.2)
+      '@vue/compiler-ssr': 3.4.13
+      '@vue/shared': 3.4.13
+      vue: 3.4.13(typescript@5.3.2)
 
   /@vue/shared@3.3.10:
     resolution: {integrity: sha512-2y3Y2J1a3RhFa0WisHvACJR2ncvWiVHcP8t0Inxo+NKz+8RKO4ZV8eZgCxRgQoA6ITfV12L4E6POOL9HOU5nqw==}
 
   /@vue/shared@3.3.11:
     resolution: {integrity: sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw==}
-
-  /@vue/shared@3.3.9:
-    resolution: {integrity: sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==}
     dev: true
 
+  /@vue/shared@3.4.13:
+    resolution: {integrity: sha512-56crFKLPpzk85WXX1L1c0QzPOuoapWlPVys8eMG8kkRmqdMjWUqK8KpFdE2d7BQA4CEbXwyyHPq6MpFr8H9rcg==}
+
   /@vue/tsconfig@0.4.0:
     resolution: {integrity: sha512-CPuIReonid9+zOG/CGTT05FXrPYATEqoDGNrEaqS4hwcw5BUNM2FguC0mOwJD4Jr16UpRVl9N0pY3P+srIbqmg==}
     dev: true
 
-  /@vueuse/core@10.6.1(vue@3.3.11):
+  /@vueuse/core@10.6.1(vue@3.4.13):
     resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==}
     dependencies:
       '@types/web-bluetooth': 0.0.20
       '@vueuse/metadata': 10.6.1
-      '@vueuse/shared': 10.6.1(vue@3.3.11)
-      vue-demi: 0.14.6(vue@3.3.11)
+      '@vueuse/shared': 10.6.1(vue@3.4.13)
+      vue-demi: 0.14.6(vue@3.4.13)
     transitivePeerDependencies:
       - '@vue/composition-api'
       - vue
@@ -1590,10 +1620,10 @@ packages:
   /@vueuse/metadata@10.6.1:
     resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==}
 
-  /@vueuse/shared@10.6.1(vue@3.3.11):
+  /@vueuse/shared@10.6.1(vue@3.4.13):
     resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==}
     dependencies:
-      vue-demi: 0.14.6(vue@3.3.11)
+      vue-demi: 0.14.6(vue@3.4.13)
     transitivePeerDependencies:
       - '@vue/composition-api'
       - vue
@@ -1654,14 +1684,14 @@ packages:
     engines: {node: '>=12'}
     dev: false
 
-  /ant-design-vue@4.0.8(vue@3.3.11):
+  /ant-design-vue@4.0.8(vue@3.4.13):
     resolution: {integrity: sha512-SyPgbiPqxgXWHywxcstJN+j9N6PoZf6y5Gvvdbb+9od+uizmh2A+TnXmIHVJ44D1V1+YjXPz1EpLfIpxqDqu9A==}
     engines: {node: '>=12.22.0'}
     peerDependencies:
       vue: '>=3.2.0'
     dependencies:
       '@ant-design/colors': 6.0.0
-      '@ant-design/icons-vue': 7.0.1(vue@3.3.11)
+      '@ant-design/icons-vue': 7.0.1(vue@3.4.13)
       '@babel/runtime': 7.23.5
       '@ctrl/tinycolor': 3.6.1
       '@emotion/hash': 0.9.1
@@ -1680,8 +1710,8 @@ packages:
       shallow-equal: 1.2.1
       stylis: 4.3.0
       throttle-debounce: 5.0.0
-      vue: 3.3.11(typescript@5.3.2)
-      vue-types: 3.0.2(vue@3.3.11)
+      vue: 3.4.13(typescript@5.3.2)
+      vue-types: 3.0.2(vue@3.4.13)
       warning: 4.0.3
     dev: false
 
@@ -2144,6 +2174,10 @@ packages:
 
   /csstype@3.1.2:
     resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+    dev: false
+
+  /csstype@3.1.3:
+    resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
 
   /dayjs@1.11.10:
     resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
@@ -2293,7 +2327,6 @@ packages:
   /entities@4.5.0:
     resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
     engines: {node: '>=0.12'}
-    dev: true
 
   /errno@0.1.8:
     resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
@@ -4096,10 +4129,10 @@ packages:
     peerDependencies:
       pinia: ^2.0.0
     dependencies:
-      pinia: 2.1.7(typescript@5.3.2)(vue@3.3.11)
+      pinia: 2.1.7(typescript@5.3.2)(vue@3.4.13)
     dev: false
 
-  /pinia@2.1.7(typescript@5.3.2)(vue@3.3.11):
+  /pinia@2.1.7(typescript@5.3.2)(vue@3.4.13):
     resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==}
     peerDependencies:
       '@vue/composition-api': ^1.4.0
@@ -4113,8 +4146,8 @@ packages:
     dependencies:
       '@vue/devtools-api': 6.5.1
       typescript: 5.3.2
-      vue: 3.3.11(typescript@5.3.2)
-      vue-demi: 0.14.6(vue@3.3.11)
+      vue: 3.4.13(typescript@5.3.2)
+      vue-demi: 0.14.6(vue@3.4.13)
     dev: false
 
   /pirates@4.0.6:
@@ -4926,7 +4959,7 @@ packages:
     dependencies:
       '@antfu/utils': 0.7.6
       '@rollup/pluginutils': 5.1.0
-      '@vueuse/core': 10.6.1(vue@3.3.11)
+      '@vueuse/core': 10.6.1(vue@3.4.13)
       fast-glob: 3.3.2
       local-pkg: 0.5.0
       magic-string: 0.30.5
@@ -4937,7 +4970,7 @@ packages:
       - rollup
     dev: true
 
-  /unplugin-vue-components@0.25.2(vue@3.3.11):
+  /unplugin-vue-components@0.25.2(vue@3.4.13):
     resolution: {integrity: sha512-OVmLFqILH6w+eM8fyt/d/eoJT9A6WO51NZLf1vC5c1FZ4rmq2bbGxTy8WP2Jm7xwFdukaIdv819+UI7RClPyCA==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -4960,17 +4993,17 @@ packages:
       minimatch: 9.0.3
       resolve: 1.22.8
       unplugin: 1.5.1
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     transitivePeerDependencies:
       - rollup
       - supports-color
     dev: true
 
-  /unplugin-vue-define-options@1.4.0(vue@3.3.11):
+  /unplugin-vue-define-options@1.4.0(vue@3.4.13):
     resolution: {integrity: sha512-P8TPXzZ1eqwkLZrGm+tHc7fR7/md6bEfSuJdxZi6Pp4PcqRctDzmZiXpQVIjBULpv+LhOCVRehIrsOTvABVUww==}
     engines: {node: '>=16.14.0'}
     dependencies:
-      '@vue-macros/common': 1.9.0(vue@3.3.11)
+      '@vue-macros/common': 1.9.0(vue@3.4.13)
       ast-walker-scope: 0.5.0
       unplugin: 1.5.1
     transitivePeerDependencies:
@@ -5021,7 +5054,7 @@ packages:
       '@types/node': 20.10.2
       rimraf: 5.0.5
       typescript: 5.3.2
-      vite: 5.0.9(@types/node@20.10.2)(less@4.2.0)
+      vite: 5.0.11(@types/node@20.10.2)(less@4.2.0)
     transitivePeerDependencies:
       - less
       - lightningcss
@@ -5031,17 +5064,17 @@ packages:
       - terser
     dev: false
 
-  /vite-svg-loader@5.1.0(vue@3.3.11):
+  /vite-svg-loader@5.1.0(vue@3.4.13):
     resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==}
     peerDependencies:
       vue: '>=3.2.13'
     dependencies:
       svgo: 3.0.5
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: true
 
-  /vite@5.0.9(@types/node@20.10.2)(less@4.2.0):
-    resolution: {integrity: sha512-wVqMd5kp28QWGgfYPDfrj771VyHTJ4UDlCteLH7bJDGDEamaz5hV8IX6h1brSGgnnyf9lI2RnzXq/JmD0c2wwg==}
+  /vite@5.0.11(@types/node@20.10.2)(less@4.2.0):
+    resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==}
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
     peerDependencies:
@@ -5076,7 +5109,7 @@ packages:
     optionalDependencies:
       fsevents: 2.3.3
 
-  /vue-demi@0.14.6(vue@3.3.11):
+  /vue-demi@0.14.6(vue@3.4.13):
     resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
     engines: {node: '>=12'}
     hasBin: true
@@ -5088,7 +5121,7 @@ packages:
       '@vue/composition-api':
         optional: true
     dependencies:
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
 
   /vue-eslint-parser@9.3.2(eslint@8.56.0):
     resolution: {integrity: sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==}
@@ -5108,13 +5141,13 @@ packages:
       - supports-color
     dev: true
 
-  /vue-router@4.2.5(vue@3.3.11):
+  /vue-router@4.2.5(vue@3.4.13):
     resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==}
     peerDependencies:
       vue: ^3.2.0
     dependencies:
       '@vue/devtools-api': 6.5.1
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
   /vue-template-compiler@2.7.15:
@@ -5136,17 +5169,17 @@ packages:
       typescript: 5.3.2
     dev: true
 
-  /vue-types@3.0.2(vue@3.3.11):
+  /vue-types@3.0.2(vue@3.4.13):
     resolution: {integrity: sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==}
     engines: {node: '>=10.15.0'}
     peerDependencies:
       vue: ^3.0.0
     dependencies:
       is-plain-object: 3.0.1
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
-  /vue3-ace-editor@2.2.4(ace-builds@1.32.0)(vue@3.3.11):
+  /vue3-ace-editor@2.2.4(ace-builds@1.32.0)(vue@3.4.13):
     resolution: {integrity: sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==}
     peerDependencies:
       ace-builds: '*'
@@ -5154,20 +5187,20 @@ packages:
     dependencies:
       ace-builds: 1.32.0
       resize-observer-polyfill: 1.5.1
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
-  /vue3-apexcharts@1.4.4(apexcharts@3.44.0)(vue@3.3.11):
+  /vue3-apexcharts@1.4.4(apexcharts@3.44.0)(vue@3.4.13):
     resolution: {integrity: sha512-TH89uZrxGjaDvkaYAISvj8+k6Bf1rUKFillc8oJirs5XZEPiwM1ELKZQ786wz0rfPqkSHHny2lqqUCK7Rw+LcQ==}
     peerDependencies:
       apexcharts: '> 3.0.0'
       vue: '> 3.0.0'
     dependencies:
       apexcharts: 3.44.0
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
-  /vue3-gettext@3.0.0-beta.3(@vue/compiler-sfc@3.3.10)(vue@3.3.11):
+  /vue3-gettext@3.0.0-beta.3(@vue/compiler-sfc@3.3.10)(vue@3.4.13):
     resolution: {integrity: sha512-zE6qKEhzlL4R/El9Z6dSg+tmXjfLorG5/Y2o+Z+DMt7dMxeYF3FQbkHzvU7DKZMXkAkkscwspmwsYAXp5ctGdA==}
     engines: {node: '>= 12.0.0'}
     hasBin: true
@@ -5185,31 +5218,31 @@ packages:
       parse5-htmlparser2-tree-adapter: 6.0.1
       pofile: 1.1.4
       tslib: 2.6.2
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
-  /vue@3.3.11(typescript@5.3.2):
-    resolution: {integrity: sha512-d4oBctG92CRO1cQfVBZp6WJAs0n8AK4Xf5fNjQCBeKCvMI1efGQ5E3Alt1slFJS9fZuPcFoiAiqFvQlv1X7t/w==}
+  /vue@3.4.13(typescript@5.3.2):
+    resolution: {integrity: sha512-FE3UZ0p+oUZTwz+SzlH/hDFg+XsVRFvwmx0LXjdD1pRK/cO4fu5v6ltAZji4za4IBih3dV78elUK3di8v3pWIg==}
     peerDependencies:
       typescript: '*'
     peerDependenciesMeta:
       typescript:
         optional: true
     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@3.3.11)
-      '@vue/shared': 3.3.11
+      '@vue/compiler-dom': 3.4.13
+      '@vue/compiler-sfc': 3.4.13
+      '@vue/runtime-dom': 3.4.13
+      '@vue/server-renderer': 3.4.13(vue@3.4.13)
+      '@vue/shared': 3.4.13
       typescript: 5.3.2
 
-  /vuedraggable@4.1.0(vue@3.3.11):
+  /vuedraggable@4.1.0(vue@3.4.13):
     resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==}
     peerDependencies:
       vue: ^3.0.1
     dependencies:
       sortablejs: 1.14.0
-      vue: 3.3.11(typescript@5.3.2)
+      vue: 3.4.13(typescript@5.3.2)
     dev: false
 
   /warning@4.0.3:

+ 1 - 1
app/src/language/LINGUAS

@@ -1 +1 @@
-es fr_FR ru_RU vi_VN zh_CN zh_TW
+en zh_CN zh_TW fr_FR es ru_RU vi_VN

+ 25 - 25
app/src/language/en/app.po

@@ -29,7 +29,7 @@ msgstr "Action"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr ""
@@ -62,7 +62,7 @@ msgstr "Saved successfully"
 msgid "Additional"
 msgstr "Add Location"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "Advance Mode"
 
@@ -139,8 +139,8 @@ msgstr "Auto-renewal enabled for %{name}"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "Back"
 
@@ -161,7 +161,7 @@ msgstr "Base information"
 msgid "Basic"
 msgstr "Basic Mode"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "Basic Mode"
 
@@ -287,7 +287,7 @@ msgstr "Configurations"
 msgid "Configure SSL"
 msgstr "Configure SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr ""
 
@@ -309,7 +309,7 @@ msgstr "CPU Status"
 msgid "CPU:"
 msgstr "CPU:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 #, fuzzy
 msgid "Create"
 msgstr "Created at"
@@ -354,7 +354,7 @@ msgstr "Database (Optional, default: database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr ""
@@ -430,8 +430,8 @@ msgstr "Disabled"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Disable auto-renewal failed for %{name}"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "Disabled"
@@ -562,7 +562,7 @@ msgstr "Saved successfully"
 msgid "Duplicate to local successfully"
 msgstr "Saved successfully"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "Edit %{n}"
 
@@ -621,9 +621,9 @@ msgstr "Enable TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "Enabled"
 
@@ -693,7 +693,7 @@ msgstr "Failed to enable %{msg}"
 msgid "Failed to get certificate information"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 
@@ -869,7 +869,7 @@ msgstr "Leave blank for no change"
 msgid "License"
 msgstr "License"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr ""
 
@@ -976,7 +976,7 @@ msgstr "Single Directive"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -1018,7 +1018,7 @@ msgstr ""
 msgid "Nginx Access Log Path"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Configuration Name"
@@ -1097,7 +1097,7 @@ msgid "Obtaining certificate"
 msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr ""
@@ -1128,7 +1128,7 @@ msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr ""
@@ -1297,7 +1297,7 @@ msgstr ""
 msgid "Removed successfully"
 msgstr "Saved successfully"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "Username"
@@ -1351,9 +1351,9 @@ msgstr ""
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "Save"
 
@@ -1379,9 +1379,9 @@ msgid "Save Successfully"
 msgstr "Saved successfully"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "Saved successfully"
 
@@ -1616,7 +1616,7 @@ msgstr "Saved successfully"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr ""
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 25 - 25
app/src/language/es/app.po

@@ -34,7 +34,7 @@ msgstr "Acción"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "Agregar"
@@ -64,7 +64,7 @@ msgstr "Agregado exitoso"
 msgid "Additional"
 msgstr "Adicional"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "Modo avanzado"
 
@@ -137,8 +137,8 @@ msgstr "Renovación automática habilitada por %{name}"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "Volver"
 
@@ -157,7 +157,7 @@ msgstr "Información general"
 msgid "Basic"
 msgstr "Básico"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "Modo Básico"
 
@@ -277,7 +277,7 @@ msgstr "Configuraciones"
 msgid "Configure SSL"
 msgstr "Configurar SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr "Conectado"
 
@@ -299,7 +299,7 @@ msgstr "Estado del CPU"
 msgid "CPU:"
 msgstr "CPU:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 msgid "Create"
 msgstr "Crear"
 
@@ -343,7 +343,7 @@ msgstr "Base de datos (Opcional, default: database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "Eliminar"
@@ -417,8 +417,8 @@ msgstr "Desactivado"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "No se pudo desactivar la renovación automática por %{name}"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "Desactivado"
@@ -543,7 +543,7 @@ msgstr "Duplicado con éxito"
 msgid "Duplicate to local successfully"
 msgstr "Duplicado con éxito a local"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "Editar %{n}"
 
@@ -601,9 +601,9 @@ msgstr "Habilitar TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "Habilitado"
 
@@ -672,7 +672,7 @@ msgstr "Error al habilitar %{msg}"
 msgid "Failed to get certificate information"
 msgstr "No se pudo obtener la información del certificado"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 "No se pudo guardar, se detectó un error(es) de sintaxis en la configuración."
@@ -846,7 +846,7 @@ msgstr "Para no modificar dejar en blanco"
 msgid "License"
 msgstr "Licencia"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr "Iniciar conexión"
 
@@ -949,7 +949,7 @@ msgstr "Directiva multilínea"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -991,7 +991,7 @@ msgstr "Nginx"
 msgid "Nginx Access Log Path"
 msgstr "Ruta de registro de acceso de Nginx"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgstr "Error de análisis de configuración de Nginx"
 
@@ -1066,7 +1066,7 @@ msgid "Obtaining certificate"
 msgstr "Obteniendo certificado"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr "Desconectado"
@@ -1097,7 +1097,7 @@ msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr "En línea"
@@ -1269,7 +1269,7 @@ msgstr "Recargando Nginx"
 msgid "Removed successfully"
 msgstr "Guardado con éxito"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "Nombre de usuario"
@@ -1322,9 +1322,9 @@ msgstr "Corriendo"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "Guardar"
 
@@ -1348,9 +1348,9 @@ msgid "Save Successfully"
 msgstr "Guardado con éxito"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "Guardado con éxito"
 
@@ -1586,7 +1586,7 @@ msgstr "Actualización exitosa"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "Actualizando Nginx UI, por favor espere..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 25 - 25
app/src/language/fr_FR/app.po

@@ -31,7 +31,7 @@ msgstr "Action"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "Ajouter"
@@ -64,7 +64,7 @@ msgstr "Mis à jour avec succés"
 msgid "Additional"
 msgstr "Supplémentaire"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "Mode avancé"
 
@@ -140,8 +140,8 @@ msgstr "Renouvellement automatique activé pour %{name}"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "Retour"
 
@@ -160,7 +160,7 @@ msgstr "Information générale"
 msgid "Basic"
 msgstr "Basique"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "Mode simple"
 
@@ -284,7 +284,7 @@ msgstr "Configurations"
 msgid "Configure SSL"
 msgstr "Configurer SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr ""
 
@@ -306,7 +306,7 @@ msgstr "État du processeur"
 msgid "CPU:"
 msgstr "CPU :"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 #, fuzzy
 msgid "Create"
 msgstr "Créé le"
@@ -351,7 +351,7 @@ msgstr "Base de données (Facultatif, par défaut : database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "Supprimer"
@@ -428,8 +428,8 @@ msgstr "Désactivé"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "La désactivation du renouvellement automatique a échoué pour %{name}"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "Désactivé"
@@ -559,7 +559,7 @@ msgstr "Dupliqué avec succès"
 msgid "Duplicate to local successfully"
 msgstr "Dupliqué avec succès"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "Modifier %{n}"
 
@@ -618,9 +618,9 @@ msgstr "Activer TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "Activé"
 
@@ -690,7 +690,7 @@ msgstr "Impossible d'activer %{msg}"
 msgid "Failed to get certificate information"
 msgstr "Échec de l'obtention des informations sur le certificat"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 "Échec de l'enregistrement, une ou plusieurs erreurs de syntaxe ont été "
@@ -865,7 +865,7 @@ msgstr "Laisser vide pour aucun changement"
 msgid "License"
 msgstr "Licence"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr ""
 
@@ -972,7 +972,7 @@ msgstr "Directive multiligne"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -1015,7 +1015,7 @@ msgstr "Journal Nginx"
 msgid "Nginx Access Log Path"
 msgstr "Chemin du journal d'accès Nginx"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgstr "Erreur d'analyse de configuration Nginx"
 
@@ -1091,7 +1091,7 @@ msgid "Obtaining certificate"
 msgstr "Obtention du certificat"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr ""
@@ -1122,7 +1122,7 @@ msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr ""
@@ -1298,7 +1298,7 @@ msgstr "Rechargement de nginx"
 msgid "Removed successfully"
 msgstr "Enregistré avec succès"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "Nom d'utilisateur"
@@ -1351,9 +1351,9 @@ msgstr "En cours d'éxécution"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "Enregistrer"
 
@@ -1377,9 +1377,9 @@ msgid "Save Successfully"
 msgstr "Sauvegarde Réussie"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "Enregistré avec succès"
 
@@ -1619,7 +1619,7 @@ msgstr "Mise à niveau réussie"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "Mise à jour de Nginx UI, veuillez patienter..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 30 - 30
app/src/language/messages.pot

@@ -26,7 +26,7 @@ msgstr ""
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr ""
@@ -57,8 +57,8 @@ msgstr ""
 msgid "Additional"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:204
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr ""
 
@@ -133,9 +133,9 @@ msgstr ""
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75
 #: src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261
+#: src/views/domain/DomainEdit.vue:256
 #: src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr ""
 
@@ -154,8 +154,8 @@ msgstr ""
 msgid "Basic"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:207
-#: src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr ""
 
@@ -276,7 +276,7 @@ msgstr ""
 msgid "Configure SSL"
 msgstr ""
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr ""
 
@@ -298,7 +298,7 @@ msgstr ""
 msgid "CPU:"
 msgstr ""
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 msgid "Create"
 msgstr ""
 
@@ -343,7 +343,7 @@ msgstr ""
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr ""
@@ -417,9 +417,9 @@ msgid "Disable auto-renewal failed for %{name}"
 msgstr ""
 
 #: src/views/domain/cert/ChangeCert.vue:48
-#: src/views/domain/DomainEdit.vue:190
+#: src/views/domain/DomainEdit.vue:185
 #: src/views/domain/DomainList.vue:36
-#: src/views/stream/StreamEdit.vue:181
+#: src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr ""
@@ -539,8 +539,8 @@ msgstr ""
 msgid "Duplicate to local successfully"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:179
-#: src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr ""
 
@@ -597,10 +597,10 @@ msgstr ""
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184
+#: src/views/domain/DomainEdit.vue:179
 #: src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175
+#: src/views/stream/StreamEdit.vue:170
 #: src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr ""
@@ -673,8 +673,8 @@ msgstr ""
 msgid "Failed to get certificate information"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:138
-#: src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133
+#: src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 
@@ -842,7 +842,7 @@ msgstr ""
 msgid "License"
 msgstr ""
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr ""
 
@@ -943,7 +943,7 @@ msgstr ""
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -986,8 +986,8 @@ msgstr ""
 msgid "Nginx Access Log Path"
 msgstr ""
 
-#: src/views/domain/DomainEdit.vue:222
-#: src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgstr ""
 
@@ -1063,7 +1063,7 @@ msgid "Obtaining certificate"
 msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr ""
@@ -1094,7 +1094,7 @@ msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr ""
@@ -1257,7 +1257,7 @@ msgstr ""
 msgid "Removed successfully"
 msgstr ""
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 msgid "Rename"
 msgstr ""
 
@@ -1306,10 +1306,10 @@ msgstr ""
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
 #: src/views/config/ConfigEdit.vue:98
-#: src/views/domain/DomainEdit.vue:268
+#: src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
 #: src/views/preference/Preference.vue:113
-#: src/views/stream/StreamEdit.vue:258
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr ""
 
@@ -1335,9 +1335,9 @@ msgstr ""
 
 #: src/views/config/ConfigEdit.vue:57
 #: src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr ""
 
@@ -1559,7 +1559,7 @@ msgstr ""
 msgid "Upgrading Nginx UI, please wait..."
 msgstr ""
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 25 - 25
app/src/language/ru_RU/app.po

@@ -29,7 +29,7 @@ msgstr "Действие"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "Добавить"
@@ -62,7 +62,7 @@ msgstr "Обновлено успешно"
 msgid "Additional"
 msgstr "Дополнительно"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "Расширенный режим"
 
@@ -139,8 +139,8 @@ msgstr "Автообновление включено для %{name}"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "Назад"
 
@@ -161,7 +161,7 @@ msgstr "Основная информация"
 msgid "Basic"
 msgstr "Простой режим"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "Простой режим"
 
@@ -287,7 +287,7 @@ msgstr "Конфигурации"
 msgid "Configure SSL"
 msgstr "Настроить SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr "Подключено"
 
@@ -309,7 +309,7 @@ msgstr "Нагрузка CPU"
 msgid "CPU:"
 msgstr "CPU:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 #, fuzzy
 msgid "Create"
 msgstr "Создан в"
@@ -354,7 +354,7 @@ msgstr "База данных (Опционально, по умолчанию:
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "Удалить"
@@ -430,8 +430,8 @@ msgstr "Отключить"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Не удалось отключить автоматическое продление для %{name}"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "Отключено"
@@ -564,7 +564,7 @@ msgstr "Продублированно"
 msgid "Duplicate to local successfully"
 msgstr "Saved successfully"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "Редактировать %{n}"
 
@@ -623,9 +623,9 @@ msgstr "Включить TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "Включено"
 
@@ -695,7 +695,7 @@ msgstr "Не удалось включить %{msg}"
 msgid "Failed to get certificate information"
 msgstr "Не удалось получить информацию о сертификате"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "Не удалось сохранить, обнаружены синтаксические ошибки в конфигурации."
 
@@ -872,7 +872,7 @@ msgstr "Оставьте пустым без изменений"
 msgid "License"
 msgstr "Лицензия"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr ""
 
@@ -979,7 +979,7 @@ msgstr "Одиночная директива"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -1022,7 +1022,7 @@ msgstr "Журнал"
 msgid "Nginx Access Log Path"
 msgstr "Путь для Nginx Access Log"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Ошибка синтаксического анализа конфигурации Nginx"
@@ -1101,7 +1101,7 @@ msgid "Obtaining certificate"
 msgstr "Получение сертификата"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr ""
@@ -1132,7 +1132,7 @@ msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr ""
@@ -1303,7 +1303,7 @@ msgstr "Перезагружается nginx"
 msgid "Removed successfully"
 msgstr "Успешно сохранено"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "Имя пользователя"
@@ -1357,9 +1357,9 @@ msgstr "Выполняется"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "Сохранить"
 
@@ -1385,9 +1385,9 @@ msgid "Save Successfully"
 msgstr "Успешно сохранено"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "Успешно сохранено"
 
@@ -1623,7 +1623,7 @@ msgstr "Обновление успешно выполнено"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "Обновление Nginx UI, подождите..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 25 - 25
app/src/language/vi_VN/app.po

@@ -29,7 +29,7 @@ msgstr "Hành động"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "Thêm"
@@ -62,7 +62,7 @@ msgstr "Cập nhật thành công"
 msgid "Additional"
 msgstr "Tùy chọn bổ sung"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "Nâng cao"
 
@@ -139,8 +139,8 @@ msgstr "Đã bật tự động gia hạn SSL cho %{name}"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "Quay lại"
 
@@ -161,7 +161,7 @@ msgstr "Thông tin"
 msgid "Basic"
 msgstr "Cơ bản"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "Cơ bản"
 
@@ -287,7 +287,7 @@ msgstr "Cấu hình"
 msgid "Configure SSL"
 msgstr "Cấu hình SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr "Đã kết nối"
 
@@ -309,7 +309,7 @@ msgstr "Trạng thái CPU"
 msgid "CPU:"
 msgstr "CPU:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 #, fuzzy
 msgid "Create"
 msgstr "Ngày tạo"
@@ -354,7 +354,7 @@ msgstr "Tên cơ sở dữ liệu (Tuỳ chọn, Mặc định là: database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "Xoá"
@@ -431,8 +431,8 @@ msgstr "Tắt"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Tắt tự động gia hạn SSL cho %{name} thất bại"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "Đã tắt"
@@ -565,7 +565,7 @@ msgstr "Nhân bản thành công"
 msgid "Duplicate to local successfully"
 msgstr "Đã sao chép thành công vào máy cục bộ"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "Sửa %{n}"
 
@@ -624,9 +624,9 @@ msgstr "Bật TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "Đã bật"
 
@@ -696,7 +696,7 @@ msgstr "Không thể bật %{msg}"
 msgid "Failed to get certificate information"
 msgstr "Không thể truy xuất thông tin chứng chỉ"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "Không lưu được, đã phát hiện thấy (các) lỗi cú pháp trong cấu hình."
 
@@ -873,7 +873,7 @@ msgstr "Bỏ trống nếu không thay đổi"
 msgid "License"
 msgstr "Giấy phép"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr "Liên kết bắt đầu"
 
@@ -979,7 +979,7 @@ msgstr "Single Directive"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -1021,7 +1021,7 @@ msgstr ""
 msgid "Nginx Access Log Path"
 msgstr "Vị trí lưu log truy cập (Access log) của Nginx"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
@@ -1100,7 +1100,7 @@ msgid "Obtaining certificate"
 msgstr "Đang nhận chứng chỉ"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr "Ngoại tuyến"
@@ -1131,7 +1131,7 @@ msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr "Trực tuyến"
@@ -1304,7 +1304,7 @@ msgstr "Tải lại nginx"
 msgid "Removed successfully"
 msgstr "Xoá thành công"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "Username"
@@ -1358,9 +1358,9 @@ msgstr "Running"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "Lưu"
 
@@ -1386,9 +1386,9 @@ msgid "Save Successfully"
 msgstr "Lưu thành công"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "Lưu thành công"
 
@@ -1622,7 +1622,7 @@ msgstr "Cập nhật thành công"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "Đang cập nhật Nginx UI, vui lòng đợi..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 25 - 25
app/src/language/zh_CN/app.po

@@ -33,7 +33,7 @@ msgstr "操作"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "添加"
@@ -63,7 +63,7 @@ msgstr "添加成功"
 msgid "Additional"
 msgstr "额外选项"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "高级模式"
 
@@ -136,8 +136,8 @@ msgstr "成功启用 %{name} 自动续签"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "返回"
 
@@ -156,7 +156,7 @@ msgstr "基本信息"
 msgid "Basic"
 msgstr "基本"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "基本模式"
 
@@ -276,7 +276,7 @@ msgstr "配置"
 msgid "Configure SSL"
 msgstr "配置 SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr "已连接"
 
@@ -298,7 +298,7 @@ msgstr "CPU 状态"
 msgid "CPU:"
 msgstr "CPU:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 msgid "Create"
 msgstr "创建"
 
@@ -342,7 +342,7 @@ msgstr "数据库 (可选,默认: database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "删除"
@@ -414,8 +414,8 @@ msgstr "禁用"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "关闭 %{name} 自动续签失败"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "禁用"
@@ -533,7 +533,7 @@ msgstr "复制成功"
 msgid "Duplicate to local successfully"
 msgstr "成功复制到本地"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
 
@@ -589,9 +589,9 @@ msgstr "启用 TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "启用"
 
@@ -659,7 +659,7 @@ msgstr "启用失败 %{msg}"
 msgid "Failed to get certificate information"
 msgstr "获取证书信息失败"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "保存失败,在配置中检测到语法错误。"
 
@@ -824,7 +824,7 @@ msgstr "留空不做任何更改"
 msgid "License"
 msgstr "开源许可"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr "链接"
 
@@ -922,7 +922,7 @@ msgstr "多行指令"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -964,7 +964,7 @@ msgstr "Nginx"
 msgid "Nginx Access Log Path"
 msgstr "Nginx 访问日志路径"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 配置解析错误"
 
@@ -1037,7 +1037,7 @@ msgid "Obtaining certificate"
 msgstr "正在获取证书"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr "离线"
@@ -1068,7 +1068,7 @@ msgstr "一旦验证完成,这些记录将被删除。"
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr "在线"
@@ -1235,7 +1235,7 @@ msgstr "正在重载 Nginx"
 msgid "Removed successfully"
 msgstr "删除成功"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 msgid "Rename"
 msgstr "重命名"
 
@@ -1283,9 +1283,9 @@ msgstr "运行中"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "保存"
 
@@ -1309,9 +1309,9 @@ msgid "Save Successfully"
 msgstr "保存成功"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "保存成功"
 
@@ -1533,7 +1533,7 @@ msgstr "升级成功"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "正在升级Nginx UI,请等待..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr "Upstream 名称"
 

+ 25 - 25
app/src/language/zh_TW/app.po

@@ -34,7 +34,7 @@ msgstr "操作"
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:141
 #: src/views/domain/ngx_conf/config_template/ConfigTemplate.vue:119
 #: src/views/domain/ngx_conf/NgxServer.vue:170
-#: src/views/domain/ngx_conf/NgxUpstream.vue:153
+#: src/views/domain/ngx_conf/NgxUpstream.vue:155
 #: src/views/stream/StreamList.vue:124
 msgid "Add"
 msgstr "新增"
@@ -66,7 +66,7 @@ msgstr "更新成功"
 msgid "Additional"
 msgstr "其他設定"
 
-#: src/views/domain/DomainEdit.vue:204 src/views/stream/StreamEdit.vue:195
+#: src/views/domain/DomainEdit.vue:199 src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgstr "進階模式"
 
@@ -140,8 +140,8 @@ msgstr "已啟用 %{name} 的自動續簽"
 
 #: src/views/certificate/CertificateEditor.vue:207
 #: src/views/config/Config.vue:75 src/views/config/ConfigEdit.vue:89
-#: src/views/domain/DomainEdit.vue:261 src/views/nginx_log/NginxLog.vue:170
-#: src/views/stream/StreamEdit.vue:251
+#: src/views/domain/DomainEdit.vue:256 src/views/nginx_log/NginxLog.vue:170
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgstr "返回"
 
@@ -160,7 +160,7 @@ msgstr "基本資訊"
 msgid "Basic"
 msgstr "基本"
 
-#: src/views/domain/DomainEdit.vue:207 src/views/stream/StreamEdit.vue:198
+#: src/views/domain/DomainEdit.vue:202 src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgstr "基本模式"
 
@@ -283,7 +283,7 @@ msgstr "設定"
 msgid "Configure SSL"
 msgstr "設定 SSL"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Connected"
 msgstr "已連結"
 
@@ -305,7 +305,7 @@ msgstr "中央處理器狀態"
 msgid "CPU:"
 msgstr "中央處理器:"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:164
+#: src/views/domain/ngx_conf/NgxUpstream.vue:166
 #, fuzzy
 msgid "Create"
 msgstr "建立時間"
@@ -350,7 +350,7 @@ msgstr "資料庫 (可選,預設: database)"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:360
 #: src/views/domain/DomainList.vue:156
 #: src/views/domain/ngx_conf/NgxServer.vue:117
-#: src/views/domain/ngx_conf/NgxUpstream.vue:127
+#: src/views/domain/ngx_conf/NgxUpstream.vue:129
 #: src/views/stream/StreamList.vue:177
 msgid "Delete"
 msgstr "刪除"
@@ -425,8 +425,8 @@ msgstr "停用"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "關閉 %{name} 自動續簽失敗"
 
-#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:190
-#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:181
+#: src/views/domain/cert/ChangeCert.vue:48 src/views/domain/DomainEdit.vue:185
+#: src/views/domain/DomainList.vue:36 src/views/stream/StreamEdit.vue:176
 #: src/views/stream/StreamList.vue:36
 msgid "Disabled"
 msgstr "停用"
@@ -548,7 +548,7 @@ msgstr "複製成功"
 msgid "Duplicate to local successfully"
 msgstr "成功複製至本機"
 
-#: src/views/domain/DomainEdit.vue:179 src/views/stream/StreamEdit.vue:170
+#: src/views/domain/DomainEdit.vue:174 src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
 
@@ -605,9 +605,9 @@ msgstr "啟用 TLS"
 
 #: src/views/domain/cert/ChangeCert.vue:44
 #: src/views/domain/components/RightSettings.vue:78
-#: src/views/domain/DomainEdit.vue:184 src/views/domain/DomainList.vue:32
+#: src/views/domain/DomainEdit.vue:179 src/views/domain/DomainList.vue:32
 #: src/views/stream/components/RightSettings.vue:78
-#: src/views/stream/StreamEdit.vue:175 src/views/stream/StreamList.vue:32
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:32
 msgid "Enabled"
 msgstr "已啟用"
 
@@ -676,7 +676,7 @@ msgstr "啟用 %{msg} 失敗"
 msgid "Failed to get certificate information"
 msgstr "取得憑證資訊失敗"
 
-#: src/views/domain/DomainEdit.vue:138 src/views/stream/StreamEdit.vue:129
+#: src/views/domain/DomainEdit.vue:133 src/views/stream/StreamEdit.vue:124
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "儲存失敗,在設定中檢測到語法錯誤。"
 
@@ -848,7 +848,7 @@ msgstr "留空表示不修改"
 msgid "License"
 msgstr "授權條款"
 
-#: src/views/dashboard/Environments.vue:90
+#: src/views/dashboard/Environments.vue:131
 msgid "Link Start"
 msgstr "連結開始"
 
@@ -950,7 +950,7 @@ msgstr "多行指令"
 #: src/views/domain/components/RightSettings.vue:84
 #: src/views/domain/components/SiteDuplicate.vue:135
 #: src/views/domain/DomainList.vue:16
-#: src/views/domain/ngx_conf/NgxUpstream.vue:176
+#: src/views/domain/ngx_conf/NgxUpstream.vue:178
 #: src/views/environment/Environment.vue:15
 #: src/views/stream/components/RightSettings.vue:84
 #: src/views/stream/components/StreamDuplicate.vue:135
@@ -992,7 +992,7 @@ msgstr "Nginx"
 msgid "Nginx Access Log Path"
 msgstr "Nginx 存取日誌路徑"
 
-#: src/views/domain/DomainEdit.vue:222 src/views/stream/StreamEdit.vue:213
+#: src/views/domain/DomainEdit.vue:217 src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 設定解析錯誤"
 
@@ -1067,7 +1067,7 @@ msgid "Obtaining certificate"
 msgstr "正在取得憑證"
 
 #: src/components/NodeSelector/NodeSelector.vue:78
-#: src/views/dashboard/Environments.vue:106
+#: src/views/dashboard/Environments.vue:98
 #: src/views/environment/Environment.vue:89
 msgid "Offline"
 msgstr "離線"
@@ -1098,7 +1098,7 @@ msgstr ""
 
 #: src/components/NodeSelector/NodeSelector.vue:57
 #: src/components/NodeSelector/NodeSelector.vue:72
-#: src/views/dashboard/Environments.vue:100
+#: src/views/dashboard/Environments.vue:91
 #: src/views/environment/Environment.vue:85
 msgid "Online"
 msgstr "線上"
@@ -1267,7 +1267,7 @@ msgstr "正在重新載入 Nginx"
 msgid "Removed successfully"
 msgstr "儲存成功"
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:124
+#: src/views/domain/ngx_conf/NgxUpstream.vue:126
 #, fuzzy
 msgid "Rename"
 msgstr "使用者名稱"
@@ -1320,9 +1320,9 @@ msgstr "執行中"
 
 #: src/components/ChatGPT/ChatGPT.vue:259
 #: src/views/certificate/CertificateEditor.vue:214
-#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:268
+#: src/views/config/ConfigEdit.vue:98 src/views/domain/DomainEdit.vue:263
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:121
-#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:258
+#: src/views/preference/Preference.vue:113 src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgstr "儲存"
 
@@ -1346,9 +1346,9 @@ msgid "Save Successfully"
 msgstr "儲存成功"
 
 #: src/views/config/ConfigEdit.vue:57 src/views/domain/DomainAdd.vue:41
-#: src/views/domain/DomainEdit.vue:154
+#: src/views/domain/DomainEdit.vue:149
 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
-#: src/views/stream/StreamEdit.vue:145
+#: src/views/stream/StreamEdit.vue:140
 msgid "Saved successfully"
 msgstr "儲存成功"
 
@@ -1579,7 +1579,7 @@ msgstr "升級成功"
 msgid "Upgrading Nginx UI, please wait..."
 msgstr "正在升級 Nginx UI,請稍候..."
 
-#: src/views/domain/ngx_conf/NgxUpstream.vue:171
+#: src/views/domain/ngx_conf/NgxUpstream.vue:173
 msgid "Upstream Name"
 msgstr ""
 

+ 1 - 1
app/src/version.json

@@ -1 +1 @@
-{"version":"2.0.0-beta.9","build_id":103,"total_build":307}
+{"version":"2.0.0-beta.9","build_id":104,"total_build":308}

+ 1 - 1
app/src/views/dashboard/ServerAnalytic.vue

@@ -12,7 +12,7 @@ const { $gettext } = useGettext()
 
 let websocket: ReconnectingWebSocket | WebSocket
 
-const host = reactive({
+const host: HostInfoStat = reactive({
   platform: '',
   platformVersion: '',
   os: '',

+ 5 - 10
app/src/views/domain/DomainEdit.vue

@@ -92,16 +92,11 @@ function init() {
 
 function handle_parse_error(e: { error?: string; message: string }) {
   console.error(e)
-  if (e?.error === 'nginx_config_syntax_error') {
-    parse_error_status.value = true
-    parse_error_message.value = e.message
-    config.get(`sites-available/${name.value}`).then(r => {
-      configText.value = r.content
-    })
-  }
-  else {
-    message.error($gettext(e?.message ?? 'Server error'))
-  }
+  parse_error_status.value = true
+  parse_error_message.value = e.message
+  config.get(`sites-available/${name.value}`).then(r => {
+    configText.value = r.content
+  })
 }
 
 function on_mode_change(advanced: boolean) {

+ 5 - 10
app/src/views/stream/StreamEdit.vue

@@ -83,16 +83,11 @@ function init() {
 
 function handle_parse_error(e: { error?: string; message: string }) {
   console.error(e)
-  if (e?.error === 'nginx_config_syntax_error') {
-    parse_error_status.value = true
-    parse_error_message.value = e.message
-    config.get(`streams-available/${name.value}`).then(r => {
-      configText.value = r.content
-    })
-  }
-  else {
-    message.error($gettext(e?.message ?? 'Server error'))
-  }
+  parse_error_status.value = true
+  parse_error_message.value = e.message
+  config.get(`streams-available/${name.value}`).then(r => {
+    configText.value = r.content
+  })
 }
 
 function on_mode_change(advanced: boolean) {

+ 1 - 1
app/version.json

@@ -1 +1 @@
-{"version":"2.0.0-beta.9","build_id":103,"total_build":307}
+{"version":"2.0.0-beta.9","build_id":104,"total_build":308}

+ 71 - 64
go.mod

@@ -14,7 +14,7 @@ require (
 	github.com/gin-contrib/static v0.0.1
 	github.com/gin-gonic/gin v1.9.1
 	github.com/go-acme/lego/v4 v4.14.2
-	github.com/go-co-op/gocron v1.36.0
+	github.com/go-co-op/gocron v1.37.0
 	github.com/go-playground/validator/v10 v10.16.0
 	github.com/golang-jwt/jwt v3.2.2+incompatible
 	github.com/google/uuid v1.5.0
@@ -25,16 +25,17 @@ require (
 	github.com/mitchellh/mapstructure v1.5.0
 	github.com/pkg/errors v0.9.1
 	github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308
-	github.com/sashabaranov/go-openai v1.17.9
-	github.com/shirou/gopsutil/v3 v3.23.11
+	github.com/sashabaranov/go-openai v1.17.11
+	github.com/shirou/gopsutil/v3 v3.23.12
 	github.com/shopspring/decimal v1.3.1
 	github.com/spf13/cast v1.6.0
-	github.com/tufanbarisyildirim/gonginx v0.0.0-20231116154738-5dd06bb2938b
+	github.com/tufanbarisyildirim/gonginx v0.0.0-20240109151651-bb3e845a7a2a
 	go.uber.org/zap v1.26.0
-	golang.org/x/crypto v0.17.0
+	golang.org/x/crypto v0.18.0
+	gopkg.in/guregu/null.v4 v4.0.0
 	gopkg.in/ini.v1 v1.67.0
 	gorm.io/driver/sqlite v1.5.4
-	gorm.io/gen v0.3.24
+	gorm.io/gen v0.3.25
 	gorm.io/gorm v1.25.5
 	gorm.io/plugin/dbresolver v1.5.0
 )
@@ -44,9 +45,9 @@ require (
 	cloud.google.com/go/compute/metadata v0.2.3 // indirect
 	github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
 	github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
-	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 // indirect
+	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
-	github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect
+	github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 // indirect
 	github.com/Azure/go-autorest v14.2.0+incompatible // indirect
@@ -58,7 +59,7 @@ require (
 	github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
 	github.com/Azure/go-autorest/logger v0.2.1 // indirect
 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
-	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
+	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
 	github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
 	github.com/CloudyKit/jet/v6 v6.2.0 // indirect
 	github.com/Joker/jade v1.1.3 // indirect
@@ -66,24 +67,24 @@ require (
 	github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect
 	github.com/StackExchange/wmi v1.2.1 // indirect
 	github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
-	github.com/aliyun/alibaba-cloud-sdk-go v1.62.619 // indirect
-	github.com/andybalholm/brotli v1.0.6 // indirect
+	github.com/aliyun/alibaba-cloud-sdk-go v1.62.654 // indirect
+	github.com/andybalholm/brotli v1.1.0 // indirect
 	github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
-	github.com/aws/aws-sdk-go-v2 v1.23.5 // indirect
-	github.com/aws/aws-sdk-go-v2/config v1.25.11 // indirect
-	github.com/aws/aws-sdk-go-v2/credentials v1.16.9 // indirect
-	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect
-	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 // indirect
-	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 // indirect
-	github.com/aws/aws-sdk-go-v2/service/lightsail v1.32.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/route53 v1.35.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 // indirect
-	github.com/aws/smithy-go v1.18.1 // indirect
+	github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
+	github.com/aws/aws-sdk-go-v2/config v1.26.3 // indirect
+	github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
+	github.com/aws/aws-sdk-go-v2/service/lightsail v1.33.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/route53 v1.37.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
+	github.com/aws/smithy-go v1.19.0 // indirect
 	github.com/aymerick/douceur v0.2.0 // indirect
 	github.com/benbjohnson/clock v1.3.5 // indirect
 	github.com/boombuler/barcode v1.0.1 // indirect
@@ -91,8 +92,8 @@ require (
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
 	github.com/chenzhuoyu/iasm v0.9.1 // indirect
-	github.com/civo/civogo v0.3.53 // indirect
-	github.com/cloudflare/cloudflare-go v0.82.0 // indirect
+	github.com/civo/civogo v0.3.56 // indirect
+	github.com/cloudflare/cloudflare-go v0.85.0 // indirect
 	github.com/cpu/goacmedns v0.1.1 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/deepmap/oapi-codegen v1.16.2 // indirect
@@ -100,6 +101,7 @@ require (
 	github.com/dnsimple/dnsimple-go v1.5.1 // indirect
 	github.com/exoscale/egoscale v0.100.1 // indirect
 	github.com/fatih/structs v1.1.0 // indirect
+	github.com/felixge/httpsnoop v1.0.4 // indirect
 	github.com/flosch/pongo2/v4 v4.0.2 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
@@ -107,7 +109,8 @@ require (
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-errors/errors v1.5.1 // indirect
 	github.com/go-jose/go-jose/v3 v3.0.1 // indirect
-	github.com/go-logr/logr v1.3.0 // indirect
+	github.com/go-logr/logr v1.4.1 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-ole/go-ole v1.3.0 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect
@@ -120,7 +123,7 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
-	github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd // indirect
+	github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/s2a-go v0.1.7 // indirect
@@ -147,7 +150,7 @@ require (
 	github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
 	github.com/kataras/blocks v0.0.8 // indirect
 	github.com/kataras/golog v0.1.11 // indirect
-	github.com/kataras/iris/v12 v12.2.8 // indirect
+	github.com/kataras/iris/v12 v12.2.9 // indirect
 	github.com/kataras/pio v0.0.13 // indirect
 	github.com/kataras/sitemap v0.0.6 // indirect
 	github.com/kataras/tunnel v0.0.4 // indirect
@@ -157,10 +160,10 @@ require (
 	github.com/kylelemons/godebug v1.1.0 // indirect
 	github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect
 	github.com/labbsr0x/goh v1.0.1 // indirect
-	github.com/labstack/echo/v4 v4.11.3 // indirect
-	github.com/labstack/gommon v0.4.1 // indirect
+	github.com/labstack/echo/v4 v4.11.4 // indirect
+	github.com/labstack/gommon v0.4.2 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
-	github.com/linode/linodego v1.25.0 // indirect
+	github.com/linode/linodego v1.27.0 // indirect
 	github.com/liquidweb/liquidweb-cli v0.7.0 // indirect
 	github.com/liquidweb/liquidweb-go v1.6.4 // indirect
 	github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect
@@ -168,7 +171,7 @@ require (
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
-	github.com/mattn/go-sqlite3 v1.14.18 // indirect
+	github.com/mattn/go-sqlite3 v1.14.19 // indirect
 	github.com/microcosm-cc/bluemonday v1.0.26 // indirect
 	github.com/miekg/dns v1.1.57 // indirect
 	github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
@@ -190,18 +193,18 @@ require (
 	github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
 	github.com/ovh/go-ovh v1.4.3 // indirect
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
-	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
-	github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
+	github.com/pelletier/go-toml/v2 v2.1.1 // indirect
+	github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
 	github.com/pquerna/otp v1.4.0 // indirect
 	github.com/robfig/cron/v3 v3.0.1 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
-	github.com/sacloud/api-client-go v0.2.9 // indirect
-	github.com/sacloud/go-http v0.1.7 // indirect
-	github.com/sacloud/iaas-api-go v1.11.1 // indirect
-	github.com/sacloud/packages-go v0.0.9 // indirect
-	github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 // indirect
+	github.com/sacloud/api-client-go v0.2.10 // indirect
+	github.com/sacloud/go-http v0.1.8 // indirect
+	github.com/sacloud/iaas-api-go v1.11.2 // indirect
+	github.com/sacloud/packages-go v0.0.10 // indirect
+	github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22 // indirect
 	github.com/schollz/closestmatch v2.1.0+incompatible // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
@@ -210,10 +213,10 @@ require (
 	github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
 	github.com/stretchr/objx v0.5.1 // indirect
 	github.com/stretchr/testify v1.8.4 // indirect
-	github.com/tdewolff/minify/v2 v2.20.8 // indirect
-	github.com/tdewolff/parse/v2 v2.7.6 // indirect
-	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.808 // indirect
-	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.808 // indirect
+	github.com/tdewolff/minify/v2 v2.20.14 // indirect
+	github.com/tdewolff/parse/v2 v2.7.9 // indirect
+	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.840 // indirect
+	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.840 // indirect
 	github.com/tklauser/go-sysconf v0.3.13 // indirect
 	github.com/tklauser/numcpus v0.7.0 // indirect
 	github.com/transip/gotransip/v6 v6.23.0 // indirect
@@ -226,30 +229,34 @@ require (
 	github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 	github.com/vultr/govultr/v2 v2.17.2 // indirect
-	github.com/yandex-cloud/go-genproto v0.0.0-20231127094019-88b7907145d1 // indirect
-	github.com/yandex-cloud/go-sdk v0.0.0-20231127094424-0eba64a6b9f1 // indirect
+	github.com/yandex-cloud/go-genproto v0.0.0-20240109074052-1761a149e810 // indirect
+	github.com/yandex-cloud/go-sdk v0.0.0-20231220065212-8e23a0060063 // indirect
 	github.com/yosssi/ace v0.0.5 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
 	go.opencensus.io v0.24.0 // indirect
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
+	go.opentelemetry.io/otel v1.21.0 // indirect
+	go.opentelemetry.io/otel/metric v1.21.0 // indirect
+	go.opentelemetry.io/otel/trace v1.21.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/ratelimit v0.3.0 // indirect
-	golang.org/x/arch v0.6.0 // indirect
-	golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
+	golang.org/x/arch v0.7.0 // indirect
+	golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
 	golang.org/x/mod v0.14.0 // indirect
-	golang.org/x/net v0.19.0 // indirect
-	golang.org/x/oauth2 v0.15.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
+	golang.org/x/net v0.20.0 // indirect
+	golang.org/x/oauth2 v0.16.0 // indirect
+	golang.org/x/sys v0.16.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
-	golang.org/x/tools v0.16.0 // indirect
-	google.golang.org/api v0.152.0 // indirect
+	golang.org/x/tools v0.17.0 // indirect
+	google.golang.org/api v0.156.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
-	google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect
-	google.golang.org/grpc v1.59.0 // indirect
-	google.golang.org/protobuf v1.31.0 // indirect
+	google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
+	google.golang.org/grpc v1.60.1 // indirect
+	google.golang.org/protobuf v1.32.0 // indirect
 	gopkg.in/fsnotify.v1 v1.4.7 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ns1/ns1-go.v2 v2.7.8 // indirect
@@ -259,10 +266,10 @@ require (
 	gorm.io/datatypes v1.2.0 // indirect
 	gorm.io/driver/mysql v1.5.2 // indirect
 	gorm.io/hints v1.1.2 // indirect
-	k8s.io/api v0.28.4 // indirect
-	k8s.io/apimachinery v0.28.4 // indirect
-	k8s.io/klog/v2 v2.110.1 // indirect
-	k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
+	k8s.io/api v0.29.0 // indirect
+	k8s.io/apimachinery v0.29.0 // indirect
+	k8s.io/klog/v2 v2.120.0 // indirect
+	k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
 )

+ 152 - 134
go.sum

@@ -604,12 +604,12 @@ github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 h1:Dy3M9aegiI7d7PF1LUdjbVigJReo+QOceYs
 github.com/AdamSLevy/jsonrpc2/v14 v14.1.0/go.mod h1:ZakZtbCXxCz82NJvq7MoREtiQesnDfrtF6RFUGzQfLo=
 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 h1:d81/ng9rET2YqdVkVwkb6EXeRrLJIwyGnJcAlAWKwhs=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 h1:lpOxwrQ919lCZoNCd69rVt8u1eLZuMORrGXqy8sNf3c=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0/go.mod h1:fSvRkb8d26z9dbL40Uf/OO6Vo9iExtZK3D0ulRV+8M0=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do=
@@ -643,8 +643,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 h1:hVeq+yCyUi+MsoO/CU95yqCIcdzra5ovzk8Q2BBpV2M=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
@@ -683,11 +683,11 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/aliyun/alibaba-cloud-sdk-go v1.62.619 h1:PHKogbOP+NmuNlmviNFxsAZzXTxXFXeA84EBuzO/1Xw=
-github.com/aliyun/alibaba-cloud-sdk-go v1.62.619/go.mod h1:CJJYa1ZMxjlN/NbXEwmejEnBkhi0DV+Yb3B2lxf+74o=
+github.com/aliyun/alibaba-cloud-sdk-go v1.62.654 h1:UpBbuyd0eqDkIfiuRmBGqdjXWd4Q7YwD9entykxwlnI=
+github.com/aliyun/alibaba-cloud-sdk-go v1.62.654/go.mod h1:CJJYa1ZMxjlN/NbXEwmejEnBkhi0DV+Yb3B2lxf+74o=
 github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
-github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
 github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
@@ -701,36 +701,36 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
-github.com/aws/aws-sdk-go-v2 v1.23.5 h1:xK6C4udTyDMd82RFvNkDQxtAd00xlzFUtX4fF2nMZyg=
-github.com/aws/aws-sdk-go-v2 v1.23.5/go.mod h1:t3szzKfP0NeRU27uBFczDivYJjsmSnqI8kIvKyWb9ds=
-github.com/aws/aws-sdk-go-v2/config v1.25.11 h1:RWzp7jhPRliIcACefGkKp03L0Yofmd2p8M25kbiyvno=
-github.com/aws/aws-sdk-go-v2/config v1.25.11/go.mod h1:BVUs0chMdygHsQtvaMyEOpW2GIW+ubrxJLgIz/JU29s=
-github.com/aws/aws-sdk-go-v2/credentials v1.16.9 h1:LQo3MUIOzod9JdUK+wxmSdgzLVYUbII3jXn3S/HJZU0=
-github.com/aws/aws-sdk-go-v2/credentials v1.16.9/go.mod h1:R7mDuIJoCjH6TxGUc/cylE7Lp/o0bhKVoxdBThsjqCM=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9 h1:FZVFahMyZle6WcogZCOxo6D/lkDA2lqKIn4/ueUmVXw=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.9/go.mod h1:kjq7REMIkxdtcEC9/4BVXjOsNY5isz6jQbEgk6osRTU=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8 h1:8GVZIR0y6JRIUNSYI1xAMF4HDfV8H/bOsZ/8AD/uY5Q=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.8/go.mod h1:rwBfu0SoUkBUZndVgPZKAD9Y2JigaZtRP68unRiYToQ=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8 h1:ZE2ds/qeBkhk3yqYvS3CDCFNvd9ir5hMjlVStLZWrvM=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.8/go.mod h1:/lAPPymDYL023+TS6DJmjuL42nxix2AvEvfjqOBRODk=
-github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw=
-github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3 h1:e3PCNeEaev/ZF01cQyNZgmYE9oYYePIMJs2mWSKG514=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.3/go.mod h1:gIeeNyaL8tIEqZrzAnTeyhHcE0yysCtcaP+N9kxLZ+E=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8 h1:EamsKe+ZjkOQjDdHd86/JCEucjFKQ9T0atWKO4s2Lgs=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.8/go.mod h1:Q0vV3/csTpbkfKLI5Sb56cJQTCTtJ0ixdb7P+Wedqiw=
-github.com/aws/aws-sdk-go-v2/service/lightsail v1.32.2 h1:mNBX6ICcERtKIvqQcoplN1w5pxR0PSBZ+8L1HQ/zILs=
-github.com/aws/aws-sdk-go-v2/service/lightsail v1.32.2/go.mod h1:/7DG3h9ZbhSqqmifeHAw7W6XRgPkl3zFHoAM7p2fUlw=
-github.com/aws/aws-sdk-go-v2/service/route53 v1.35.2 h1:Dd8CLHufmDFPt+ccGpJx4S0/tS9MnUGPZ9PqU9k6z08=
-github.com/aws/aws-sdk-go-v2/service/route53 v1.35.2/go.mod h1:D58n83ihSAC0wtkcvU6PavqmO839sqYQ+HvpqbD7tKE=
-github.com/aws/aws-sdk-go-v2/service/sso v1.18.2 h1:xJPydhNm0Hiqct5TVKEuHG7weC0+sOs4MUnd7A5n5F4=
-github.com/aws/aws-sdk-go-v2/service/sso v1.18.2/go.mod h1:zxk6y1X2KXThESWMS5CrKRvISD8mbIMab6nZrCGxDG0=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2 h1:8dU9zqA77C5egbU6yd4hFLaiIdPv3rU+6cp7sz5FjCU=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.2/go.mod h1:7Lt5mjQ8x5rVdKqg+sKKDeuwoszDJIIPmkd8BVsEdS0=
-github.com/aws/aws-sdk-go-v2/service/sts v1.26.2 h1:fFrLsy08wEbAisqW3KDl/cPHrF43GmV79zXB9EwJiZw=
-github.com/aws/aws-sdk-go-v2/service/sts v1.26.2/go.mod h1:7Ld9eTqocTvJqqJ5K/orbSDwmGcpRdlDiLjz2DO+SL8=
-github.com/aws/smithy-go v1.18.1 h1:pOdBTUfXNazOlxLrgeYalVnuTpKreACHtc62xLwIB3c=
-github.com/aws/smithy-go v1.18.1/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
+github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
+github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
+github.com/aws/aws-sdk-go-v2/config v1.26.3 h1:dKuc2jdp10y13dEEvPqWxqLoc0vF3Z9FC45MvuQSxOA=
+github.com/aws/aws-sdk-go-v2/config v1.26.3/go.mod h1:Bxgi+DeeswYofcYO0XyGClwlrq3DZEXli0kLf4hkGA0=
+github.com/aws/aws-sdk-go-v2/credentials v1.16.14 h1:mMDTwwYO9A0/JbOCOG7EOZHtYM+o7OfGWfu0toa23VE=
+github.com/aws/aws-sdk-go-v2/credentials v1.16.14/go.mod h1:cniAUh3ErQPHtCQGPT5ouvSAQ0od8caTO9OOuufZOAE=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
+github.com/aws/aws-sdk-go-v2/service/lightsail v1.33.0 h1:n4xwbBTjtQVc5Vae3Sc/Qc5pPSdtV6ufofeQ+3NGU8w=
+github.com/aws/aws-sdk-go-v2/service/lightsail v1.33.0/go.mod h1:35MKNS46RX7Lb9EIFP2bPy3WrJu+bxU6QgLis8K1aa4=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.37.0 h1:f3hBZWtpn9clZGXJoqahQeec9ZPZnu22g8pg+zNyif0=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.37.0/go.mod h1:8qqfpG4mug2JLlEyWPSFhEGvJiaZ9iPmMDDMYc5Xtas=
+github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac=
+github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 h1:Yf2MIo9x+0tyv76GljxzqA3WtC5mw7NmazD2chwjxE4=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
+github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
+github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
+github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
+github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -775,11 +775,11 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
 github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
-github.com/civo/civogo v0.3.53 h1:PYqwTwt9YmeBRKMzfuTXBSPtE0WIsbLzhxD3V36bVlo=
-github.com/civo/civogo v0.3.53/go.mod h1:54lv/FOf7gh6wE9ZwVdw4yBehk8V1CvU9aWa4v6dvW0=
+github.com/civo/civogo v0.3.56 h1:t5u/OwExb2ibVmIXsUprV5m++bAqBRLO9uMcodNHZek=
+github.com/civo/civogo v0.3.56/go.mod h1:54lv/FOf7gh6wE9ZwVdw4yBehk8V1CvU9aWa4v6dvW0=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/cloudflare-go v0.82.0 h1:t4G5BcutMcd+3U1FJHifo7Gv3m3LCzhARKZDinSi9Qs=
-github.com/cloudflare/cloudflare-go v0.82.0/go.mod h1:W9Tg8ntSvkoWs/YpwuucBf6ZaG5wTcUSLhyg6GH/zBg=
+github.com/cloudflare/cloudflare-go v0.85.0 h1:GO5Alu5ldNdPyh5i9VSSM5ZdjL57u76Y4HNmwKKyHmA=
+github.com/cloudflare/cloudflare-go v0.85.0/go.mod h1:Cj+RG+ceGsRexXYLRydfTB7pjODi3YO5KeG6vnLV2cA=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -849,6 +849,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
 github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
 github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
 github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
@@ -876,8 +878,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU
 github.com/go-acme/lego/v4 v4.14.2 h1:/D/jqRgLi8Cbk33sLGtu2pX2jEg3bGJWHyV8kFuUHGM=
 github.com/go-acme/lego/v4 v4.14.2/go.mod h1:kBXxbeTg0x9AgaOYjPSwIeJy3Y33zTz+tMD16O4MO6c=
 github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
-github.com/go-co-op/gocron v1.36.0 h1:sEmAwg57l4JWQgzaVWYfKZ+w13uHOqeOtwjo72Ll5Wc=
-github.com/go-co-op/gocron v1.36.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
+github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
+github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
 github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
@@ -902,9 +904,12 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
 github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
-github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
 github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
@@ -1004,8 +1009,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd h1:PppHBegd3uPZ3Y/Iax/2mlCFJm1w4Qf/zP1MdW4ju2o=
-github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
+github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k=
+github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
@@ -1225,8 +1230,8 @@ github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM=
 github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg=
 github.com/kataras/golog v0.1.11 h1:dGkcCVsIpqiAMWTlebn/ZULHxFvfG4K43LF1cNWSh20=
 github.com/kataras/golog v0.1.11/go.mod h1:mAkt1vbPowFUuUGvexyQ5NFW6djEgGyxQBIARJ0AH4A=
-github.com/kataras/iris/v12 v12.2.8 h1:p+PcqyO45dSib8B4I8Wc0fz+6B/CVkOsikCpbeNOkuo=
-github.com/kataras/iris/v12 v12.2.8/go.mod h1:on94BX0C5jhuxgWKDZVpcTqymksZDIxWFN+nL7axjRA=
+github.com/kataras/iris/v12 v12.2.9 h1:vSrjFmZRfXqHjmkvitj32O5JtEVrbPPHXxrAIqidJcM=
+github.com/kataras/iris/v12 v12.2.9/go.mod h1:lgp2aaapAct2HRdQMn4zIgKqWET7WfW1LWEwDElxxHA=
 github.com/kataras/pio v0.0.13 h1:x0rXVX0fviDTXOOLOmr4MUxOabu1InVSTu5itF8CXCM=
 github.com/kataras/pio v0.0.13/go.mod h1:k3HNuSw+eJ8Pm2lA4lRhg3DiCjVgHlP8hmXApSej3oM=
 github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY=
@@ -1267,17 +1272,17 @@ github.com/labbsr0x/bindman-dns-webhook v1.0.2 h1:I7ITbmQPAVwrDdhd6dHKi+MYJTJqPC
 github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
 github.com/labbsr0x/goh v1.0.1 h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk=
 github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
-github.com/labstack/echo/v4 v4.11.3 h1:Upyu3olaqSHkCjs1EJJwQ3WId8b8b1hxbogyommKktM=
-github.com/labstack/echo/v4 v4.11.3/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws=
-github.com/labstack/gommon v0.4.1 h1:gqEff0p/hTENGMABzezPoPSRtIh1Cvw0ueMOe0/dfOk=
-github.com/labstack/gommon v0.4.1/go.mod h1:TyTrpPqxR5KMk8LKVtLmfMjeQ5FEkBYdxLYPw/WfrOM=
+github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
+github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
+github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
+github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
 github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
 github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
 github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/linode/linodego v1.25.0 h1:zYMz0lTasD503jBu3tSRhzEmXHQN1zptCw5o71ibyyU=
-github.com/linode/linodego v1.25.0/go.mod h1:BMZI0pMM/YGjBis7pIXDPbcgYfCZLH0/UvzqtsGtG1c=
+github.com/linode/linodego v1.27.0 h1:ISRsasemj/bG+jAxs1k6bTTeOJcp+Xpm810SY3GoI0k=
+github.com/linode/linodego v1.27.0/go.mod h1:kD7Bf1piWg/AXb9TA0ThAVwzR+GPf6r2PvbTbVk7PMA=
 github.com/liquidweb/go-lwApi v0.0.0-20190605172801-52a4864d2738/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs=
 github.com/liquidweb/go-lwApi v0.0.5/go.mod h1:0sYF9rMXb0vlG+4SzdiGMXHheCZxjguMq+Zb4S2BfBs=
 github.com/liquidweb/liquidweb-cli v0.6.9/go.mod h1:cE1uvQ+x24NGUL75D0QagOFCG8Wdvmwu8aL9TLmA/eQ=
@@ -1321,8 +1326,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
 github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
-github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
-github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI=
+github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
@@ -1428,8 +1433,9 @@ github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmv
 github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
 github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
 github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
-github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
 github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
+github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
+github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
 github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
@@ -1443,14 +1449,14 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
-github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
-github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
+github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
+github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
 github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
 github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
 github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
-github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
-github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -1516,28 +1522,28 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF
 github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/sacloud/api-client-go v0.2.9 h1:oNZ6usbBre8SeqBp5gpLOKg0ScpvHEwyJOU92Y/47M8=
-github.com/sacloud/api-client-go v0.2.9/go.mod h1:PivzNlDl/8L5pTycvD/KzSAo9hKRl3qlqmVunSqjgJY=
-github.com/sacloud/go-http v0.1.7 h1:oBnoTLTlu4afkRJHIQSV6NJMUfIR1S3rB/SQaGzL/3Q=
-github.com/sacloud/go-http v0.1.7/go.mod h1:WV31q5qAUt6Rs7dfqQfGyRprXhf91jS+41FofYHmxUI=
-github.com/sacloud/iaas-api-go v1.11.1 h1:2MsFZ4H1uRdRVx2nVXuERWQ3swoFc3XreIV5hJ3Nsws=
-github.com/sacloud/iaas-api-go v1.11.1/go.mod h1:uBDSa06F/V0OnoR66jGdbH0PVnCJw+NeE9RVbVgMfss=
-github.com/sacloud/packages-go v0.0.9 h1:GbinkBLC/eirFhHpLjoDW6JV7+95Rnd2d8RWj7Afeks=
-github.com/sacloud/packages-go v0.0.9/go.mod h1:k+EEUMF2LlncjbNIJNOqLyZ9wjTESPIWIk1OA7x9j2Q=
+github.com/sacloud/api-client-go v0.2.10 h1:+rv3jDohD+pkdYwOTBiB+jZsM0xK3AxadXRzhp3q66c=
+github.com/sacloud/api-client-go v0.2.10/go.mod h1:Jj3CTy2+O4bcMedVDXlbHuqqche85HEPuVXoQFhLaRc=
+github.com/sacloud/go-http v0.1.8 h1:ynreWA/vnM8G2ksbMlmefBHsXURKPz49qlPRqQ9IQdw=
+github.com/sacloud/go-http v0.1.8/go.mod h1:7TL7TN1fnPKHsMifIqURDkGujnKViCgEz5Ei/LQdFK8=
+github.com/sacloud/iaas-api-go v1.11.2 h1:2jQLPwGRK/sS9bjvjWFWk2AFToU2Zq2o+6JP5Uvhqu8=
+github.com/sacloud/iaas-api-go v1.11.2/go.mod h1:gjiuIY5c/7lj2LmFnVgyHcPMT17PysXpNPBrmVMV8dM=
+github.com/sacloud/packages-go v0.0.10 h1:UiQGjy8LretewkRhsuna1TBM9Vz/l9FoYpQx+D+AOck=
+github.com/sacloud/packages-go v0.0.10/go.mod h1:f8QITBh9z4IZc4yE9j21Q8b0sXEMwRlRmhhjWeDVTYs=
 github.com/sagikazarmark/crypt v0.10.0/go.mod h1:gwTNHQVoOS3xp9Xvz5LLR+1AauC5M6880z5NWzdhOyQ=
 github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
 github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
-github.com/sashabaranov/go-openai v1.17.9 h1:QEoBiGKWW68W79YIfXWEFZ7l5cEgZBV4/Ow3uy+5hNY=
-github.com/sashabaranov/go-openai v1.17.9/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
-github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 h1:yWfiTPwYxB0l5fGMhl/G+liULugVIHD9AU77iNLrURQ=
-github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
+github.com/sashabaranov/go-openai v1.17.11 h1:XVr00J8JymJVx8Hjbh/5mG0V4PQHRarBU3v7k2x6MR0=
+github.com/sashabaranov/go-openai v1.17.11/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
+github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22 h1:wJrcTdddKOI8TFxs8cemnhKP2EmKy3yfUKHj3ZdfzYo=
+github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
 github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk=
 github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
-github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ=
-github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
+github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
+github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
 github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
 github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
 github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
@@ -1611,16 +1617,17 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
-github.com/tdewolff/minify/v2 v2.20.8 h1:OqDc95F0OK239T7P5g5oL5XthQtOtKbhbhM9GKc2W9g=
-github.com/tdewolff/minify/v2 v2.20.8/go.mod h1:hZnNtFqXVQ5QIAR05tdgvS7h6E80jyRwHSGVmM4jbzQ=
-github.com/tdewolff/parse/v2 v2.7.6 h1:PGZH2b/itDSye9RatReRn4GBhsT+KFEMtAMjHRuY1h8=
-github.com/tdewolff/parse/v2 v2.7.6/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
-github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52 h1:gAQliwn+zJrkjAHVcBEYW/RFvd2St4yYimisvozAYlA=
+github.com/tdewolff/minify/v2 v2.20.14 h1:sktSuVixRwk0ryQjqvKBu/uYS+MWmkwEFMEWtFZ+TdE=
+github.com/tdewolff/minify/v2 v2.20.14/go.mod h1:qnIJbnG2dSzk7LIa/UUwgN2OjS8ir6RRlqc0T/1q2xY=
+github.com/tdewolff/parse/v2 v2.7.9 h1:4u8nNXNmEGCRVd/slZmZHFL1mv/EVEpHMhSinxdDCqw=
+github.com/tdewolff/parse/v2 v2.7.9/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
 github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.808 h1:tOcS95xyLkY8OyquoVpQiH8i0zkkMcttW30Kr4a/oOo=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.808/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.808 h1:DI5mlNI3Ybfwjlet8+f4OW1i79hEpZyqLvPF/d3Kk/E=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.808/go.mod h1:BV+ITDBPJ377xJCaetYXRhJOQ0mybMuDoFzlAWvwM4M=
+github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
+github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.840 h1:9USk5SB/KJCQ+UJWkrpX9rHQjXNNmh+JkqhJqe0BbJ8=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.840/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.840 h1:miQt5xs8Zxnf7kCHxt+dIrt2x4IQf8lhEbPhTlp2PVQ=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.840/go.mod h1:kivFFN5aDd8yBEetdtQ6QBTww3YuvJhAwW4mVfMJ6hM=
 github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
 github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
 github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
@@ -1630,8 +1637,8 @@ github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDgu
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/transip/gotransip/v6 v6.23.0 h1:PsTdjortrEZ8IFFifEryzjVjOy9SgK4ahlnhKBBIQgA=
 github.com/transip/gotransip/v6 v6.23.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c=
-github.com/tufanbarisyildirim/gonginx v0.0.0-20231116154738-5dd06bb2938b h1:RBedKep0bACMIX35bTac14nNTrdxP1orDe6UsLnXyws=
-github.com/tufanbarisyildirim/gonginx v0.0.0-20231116154738-5dd06bb2938b/go.mod h1:4fTjBxMoWGOIVnGFSTS9GAZ0yMyiGzTdATQS0krQv18=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20240109151651-bb3e845a7a2a h1:LXXKkDwOLvH/+Eqdjw+5OzpFDNnsivpLr5rcaQ857vI=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20240109151651-bb3e845a7a2a/go.mod h1:4fTjBxMoWGOIVnGFSTS9GAZ0yMyiGzTdATQS0krQv18=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
 github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
@@ -1666,10 +1673,11 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
-github.com/yandex-cloud/go-genproto v0.0.0-20231127094019-88b7907145d1 h1:RSI7d8Iuq3LkdFBaFw8FHRCY5HWxxCQdb7P1XOPSPkw=
-github.com/yandex-cloud/go-genproto v0.0.0-20231127094019-88b7907145d1/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
-github.com/yandex-cloud/go-sdk v0.0.0-20231127094424-0eba64a6b9f1 h1:+Tb9JZbAZnC/hDlutcXtTpyIzH7+WSKt31235KdgQfs=
-github.com/yandex-cloud/go-sdk v0.0.0-20231127094424-0eba64a6b9f1/go.mod h1:Hn8brX0FKQYPT5GJrBxZNsw6UpajloU1rSJaDbRry0A=
+github.com/yandex-cloud/go-genproto v0.0.0-20231220064917-199880d921bc/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
+github.com/yandex-cloud/go-genproto v0.0.0-20240109074052-1761a149e810 h1:lPn35elCrDiYoNUnQh1m5WrALieF+1kqVhm01/FQIFg=
+github.com/yandex-cloud/go-genproto v0.0.0-20240109074052-1761a149e810/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
+github.com/yandex-cloud/go-sdk v0.0.0-20231220065212-8e23a0060063 h1:4ax9uzn9uZ2ay8xoYHSuaUjblqG9TEsaXEeMXJwFE4o=
+github.com/yandex-cloud/go-sdk v0.0.0-20231220065212-8e23a0060063/go.mod h1:37xCFSQ779Njk5Lgh0Ih6FKHqpxItFJWenYnREAd0MU=
 github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=
 github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
 github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
@@ -1703,6 +1711,14 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
+go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
+go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
+go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
+go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
+go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
+go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
 go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
@@ -1727,8 +1743,8 @@ go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
 go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
-golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
+golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -1752,8 +1768,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
 golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1769,8 +1785,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
-golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
-golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
+golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
+golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -1892,8 +1908,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
-golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
+golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1923,8 +1939,8 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec
 golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
 golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
-golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
-golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
+golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
+golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1941,8 +1957,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2017,7 +2033,6 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2060,8 +2075,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
 golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -2074,8 +2090,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2177,8 +2193,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
-golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
-golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
+golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
+golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2253,8 +2269,8 @@ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60c
 google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
 google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
 google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
-google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY=
-google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
+google.golang.org/api v0.156.0 h1:yloYcGbBtVYjLKQe4enCunxvwn3s2w/XPrrhVf6MsvQ=
+google.golang.org/api v0.156.0/go.mod h1:bUSmn4KFO0Q+69zo9CNIDp4Psi6BqM0np0CbzKRSiSY=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -2398,12 +2414,12 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl
 google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
 google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
-google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 h1:W12Pwm4urIbRdGhMEg2NM9O3TWKjNcxQhs46V0ypf/k=
-google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic=
-google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 h1:ZcOkrmX74HbKFYnpPY8Qsw93fC29TbJXspYKaBkSXDQ=
-google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM=
+google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 h1:/IWabOtPziuXTEtI1KYCpM6Ss7vaAkeMxk+uXV/xvZs=
+google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
+google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo=
+google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -2446,8 +2462,8 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v
 google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
 google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
 google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
-google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
-google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
+google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
+google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -2466,8 +2482,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
+google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -2479,6 +2495,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg=
+gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI=
 gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
 gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -2522,8 +2540,8 @@ gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
 gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
 gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
 gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
-gorm.io/gen v0.3.24 h1:yL1RrCySwTWTQpkUkt2FCe42Xub2eaZP2tM5EQoFBNU=
-gorm.io/gen v0.3.24/go.mod h1:G9uxGfkfNFxPoOrV5P6KQxRMgZsQSCyp9vJP8xiKTGg=
+gorm.io/gen v0.3.25 h1:uT/1YfvcnYUdike4XPYyi89FEnVHZF115GUXQm2Sfug=
+gorm.io/gen v0.3.25/go.mod h1:p+t0iCKjaPz+pKRxcx63nXdRgnrah/QD2l92747ihyA=
 gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
 gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
 gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
@@ -2546,23 +2564,23 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
 k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E=
-k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
-k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
+k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A=
+k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA=
 k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM=
-k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
-k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
+k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o=
+k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis=
 k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
 k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
-k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
+k8s.io/klog/v2 v2.120.0 h1:z+q5mfovBj1fKFxiRzsa2DsJLPIVMk/KFL81LMOfK+8=
+k8s.io/klog/v2 v2.120.0/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
 k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
-k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=
+k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
 lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
 modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=

+ 6 - 3
internal/nginx/build_config.go

@@ -17,8 +17,7 @@ func buildComments(orig string, indent int) (content string) {
 	return
 }
 
-func (c *NgxConfig) BuildConfig() (content string) {
-
+func (c *NgxConfig) BuildConfig() (content string, err error) {
 	// Custom
 	if c.Custom != "" {
 		content += c.Custom
@@ -84,7 +83,11 @@ func (c *NgxConfig) BuildConfig() (content string) {
 		content += fmt.Sprintf("%sserver {\n%s}\n\n", comments, server)
 	}
 	p := parser.NewStringParser(content)
-	config := p.Parse()
+	config, err := p.Parse()
+	if err != nil {
+		return
+	}
+
 	content = gonginx.DumpConfig(config, gonginx.IndentedStyle)
 	return
 }

+ 5 - 2
internal/nginx/format_code.go

@@ -10,9 +10,12 @@ func (c *NgxConfig) FmtCode() (fmtContent string) {
 	return
 }
 
-func FmtCode(content string) (fmtContent string) {
+func FmtCode(content string) (fmtContent string, err error) {
 	p := parser.NewStringParser(content)
-	c := p.Parse()
+	c, err := p.Parse()
+	if err != nil {
+		return
+	}
 	fmtContent = gonginx.DumpConfig(c, gonginx.IndentedStyle)
 	return
 }

+ 19 - 7
internal/nginx/parse.go

@@ -127,8 +127,9 @@ func buildComment(c []string) string {
 	return strings.ReplaceAll(strings.Join(c, "\n"), "#", "")
 }
 
-func parse(block gonginx.IBlock, ngxConfig *NgxConfig) {
+func parse(block gonginx.IBlock, ngxConfig *NgxConfig) (err error) {
 	if block == nil {
+		err = errors.New("block is nil")
 		return
 	}
 	for _, v := range block.GetDirectives() {
@@ -152,15 +153,23 @@ func parse(block gonginx.IBlock, ngxConfig *NgxConfig) {
 			ngxConfig.parseCustom(v)
 		}
 	}
-	ngxConfig.Custom = FmtCode(ngxConfig.Custom)
+	custom, err := FmtCode(ngxConfig.Custom)
+	if err != nil {
+		return
+	}
+	ngxConfig.Custom = custom
+	return
 }
 
-func ParseNgxConfigByContent(content string) (ngxConfig *NgxConfig) {
+func ParseNgxConfigByContent(content string) (ngxConfig *NgxConfig, err error) {
 	p := parser.NewStringParser(content)
-	c := p.Parse()
+	c, err := p.Parse()
+	if err != nil {
+		return
+	}
 	ngxConfig = NewNgxConfig("")
 	ngxConfig.c = c
-	parse(c.Block, ngxConfig)
+	err = parse(c.Block, ngxConfig)
 	return
 }
 
@@ -169,9 +178,12 @@ func ParseNgxConfig(filename string) (ngxConfig *NgxConfig, err error) {
 	if err != nil {
 		return nil, errors.Wrap(err, "error ParseNgxConfig")
 	}
-	c := p.Parse()
+	c, err := p.Parse()
+	if err != nil {
+		return
+	}
 	ngxConfig = NewNgxConfig(filename)
 	ngxConfig.c = c
-	parse(c.Block, ngxConfig)
+	err = parse(c.Block, ngxConfig)
 	return
 }

+ 4 - 1
internal/template/template.go

@@ -164,7 +164,10 @@ func ParseTemplate(path, name string, bindData map[string]Variable) (c ConfigDet
 	content = buf.String()
 
 	p := parser.NewStringParser(content)
-	config := p.Parse()
+	config, err := p.Parse()
+	if err != nil {
+		return
+	}
 	c.Custom = custom
 	for _, d := range config.GetDirectives() {
 		switch d.GetName() {

+ 0 - 9
router/middleware.go

@@ -8,7 +8,6 @@ import (
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-contrib/static"
 	"github.com/gin-gonic/gin"
-	"github.com/spf13/cast"
 	"io/fs"
 	"net/http"
 	"path"
@@ -20,20 +19,12 @@ func recovery() gin.HandlerFunc {
 	return func(c *gin.Context) {
 		defer func() {
 			if err := recover(); err != nil {
-				errorAction := "panic"
-				if action, ok := c.Get("maybe_error"); ok {
-					errorActionMsg := cast.ToString(action)
-					if errorActionMsg != "" {
-						errorAction = errorActionMsg
-					}
-				}
 				buf := make([]byte, 1024)
 				runtime.Stack(buf, false)
 				logger.Errorf("%s\n%s", err, buf)
 
 				c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
 					"message": err.(error).Error(),
-					"error":   errorAction,
 				})
 			}
 		}()