Compare commits
3 Commits
fdf2c477f2
...
635cd6ca8b
Author | SHA1 | Date |
---|---|---|
Lykin | 635cd6ca8b | |
Lykin | aa291f742d | |
Lykin | 2d2954d81c |
|
@ -494,27 +494,68 @@ func (b *browserService) scanKeys(ctx context.Context, client redis.UniversalCli
|
||||||
return keys, cursor, nil
|
return keys, cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if key exists
|
||||||
|
func (b *browserService) existsKey(ctx context.Context, client redis.UniversalClient, key, keyType string) bool {
|
||||||
|
var keyExists atomic.Bool
|
||||||
|
if cluster, ok := client.(*redis.ClusterClient); ok {
|
||||||
|
// cluster mode
|
||||||
|
cluster.ForEachMaster(ctx, func(ctx context.Context, cli *redis.Client) error {
|
||||||
|
if n := cli.Exists(ctx, key).Val(); n > 0 {
|
||||||
|
if len(keyType) <= 0 || strings.ToLower(keyType) == cli.Type(ctx, key).Val() {
|
||||||
|
keyExists.Store(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if n := client.Exists(ctx, key).Val(); n > 0 {
|
||||||
|
if len(keyType) <= 0 || strings.ToLower(keyType) == client.Type(ctx, key).Val() {
|
||||||
|
keyExists.Store(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyExists.Load()
|
||||||
|
}
|
||||||
|
|
||||||
// LoadNextKeys load next key from saved cursor
|
// LoadNextKeys load next key from saved cursor
|
||||||
func (b *browserService) LoadNextKeys(server string, db int, match, keyType string) (resp types.JSResp) {
|
func (b *browserService) LoadNextKeys(server string, db int, match, keyType string, exactMatch bool) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(server, db)
|
item, err := b.getRedisClient(server, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if match == "*" {
|
||||||
|
exactMatch = false
|
||||||
|
}
|
||||||
|
|
||||||
client, ctx, count := item.client, item.ctx, item.stepSize
|
client, ctx, count := item.client, item.ctx, item.stepSize
|
||||||
|
var matchKeys []any
|
||||||
|
var maxKeys int64
|
||||||
cursor := item.cursor[db]
|
cursor := item.cursor[db]
|
||||||
keys, cursor, err := b.scanKeys(ctx, client, match, keyType, cursor, count)
|
fullScan := match == "*" || match == ""
|
||||||
|
if exactMatch && !fullScan {
|
||||||
|
if b.existsKey(ctx, client, match, keyType) {
|
||||||
|
matchKeys = []any{match}
|
||||||
|
maxKeys = 1
|
||||||
|
}
|
||||||
|
b.setClientCursor(server, db, 0)
|
||||||
|
} else {
|
||||||
|
matchKeys, cursor, err = b.scanKeys(ctx, client, match, keyType, cursor, count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.setClientCursor(server, db, cursor)
|
b.setClientCursor(server, db, cursor)
|
||||||
maxKeys := b.loadDBSize(ctx, client)
|
if fullScan {
|
||||||
|
maxKeys = b.loadDBSize(ctx, client)
|
||||||
|
} else {
|
||||||
|
maxKeys = int64(len(matchKeys))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
resp.Data = map[string]any{
|
resp.Data = map[string]any{
|
||||||
"keys": keys,
|
"keys": matchKeys,
|
||||||
"end": cursor == 0,
|
"end": cursor == 0,
|
||||||
"maxKeys": maxKeys,
|
"maxKeys": maxKeys,
|
||||||
}
|
}
|
||||||
|
@ -522,7 +563,7 @@ func (b *browserService) LoadNextKeys(server string, db int, match, keyType stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadNextAllKeys load next all keys
|
// LoadNextAllKeys load next all keys
|
||||||
func (b *browserService) LoadNextAllKeys(server string, db int, match, keyType string) (resp types.JSResp) {
|
func (b *browserService) LoadNextAllKeys(server string, db int, match, keyType string, exactMatch bool) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(server, db)
|
item, err := b.getRedisClient(server, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
|
@ -530,25 +571,39 @@ func (b *browserService) LoadNextAllKeys(server string, db int, match, keyType s
|
||||||
}
|
}
|
||||||
|
|
||||||
client, ctx := item.client, item.ctx
|
client, ctx := item.client, item.ctx
|
||||||
|
var matchKeys []any
|
||||||
|
var maxKeys int64
|
||||||
|
fullScan := match == "*" || match == ""
|
||||||
|
if exactMatch && !fullScan {
|
||||||
|
if b.existsKey(ctx, client, match, keyType) {
|
||||||
|
matchKeys = []any{match}
|
||||||
|
maxKeys = 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
cursor := item.cursor[db]
|
cursor := item.cursor[db]
|
||||||
keys, _, err := b.scanKeys(ctx, client, match, keyType, cursor, 0)
|
matchKeys, _, err = b.scanKeys(ctx, client, match, keyType, cursor, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.setClientCursor(server, db, 0)
|
b.setClientCursor(server, db, 0)
|
||||||
maxKeys := b.loadDBSize(ctx, client)
|
if fullScan {
|
||||||
|
maxKeys = b.loadDBSize(ctx, client)
|
||||||
|
} else {
|
||||||
|
maxKeys = int64(len(matchKeys))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
resp.Data = map[string]any{
|
resp.Data = map[string]any{
|
||||||
"keys": keys,
|
"keys": matchKeys,
|
||||||
"maxKeys": maxKeys,
|
"maxKeys": maxKeys,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadAllKeys load all keys
|
// LoadAllKeys load all keys
|
||||||
func (b *browserService) LoadAllKeys(server string, db int, match, keyType string) (resp types.JSResp) {
|
func (b *browserService) LoadAllKeys(server string, db int, match, keyType string, exactMatch bool) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(server, db)
|
item, err := b.getRedisClient(server, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
|
@ -556,15 +611,23 @@ func (b *browserService) LoadAllKeys(server string, db int, match, keyType strin
|
||||||
}
|
}
|
||||||
|
|
||||||
client, ctx := item.client, item.ctx
|
client, ctx := item.client, item.ctx
|
||||||
keys, _, err := b.scanKeys(ctx, client, match, keyType, 0, 0)
|
var matchKeys []any
|
||||||
|
fullScan := match == "*" || match == ""
|
||||||
|
if exactMatch && !fullScan {
|
||||||
|
if b.existsKey(ctx, client, match, keyType) {
|
||||||
|
matchKeys = []any{match}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matchKeys, _, err = b.scanKeys(ctx, client, match, keyType, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
resp.Data = map[string]any{
|
resp.Data = map[string]any{
|
||||||
"keys": keys,
|
"keys": matchKeys,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,6 @@ func (c *connectionService) buildOption(config types.ConnectionConfig) (*redis.O
|
||||||
if config.SSH.Enable {
|
if config.SSH.Enable {
|
||||||
sshConfig = &ssh.ClientConfig{
|
sshConfig = &ssh.ClientConfig{
|
||||||
User: config.SSH.Username,
|
User: config.SSH.Username,
|
||||||
Auth: []ssh.AuthMethod{ssh.Password(config.SSH.Password)},
|
|
||||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||||
Timeout: time.Duration(config.ConnTimeout) * time.Second,
|
Timeout: time.Duration(config.ConnTimeout) * time.Second,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,26 @@
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.1",
|
"chart.js": "^4.4.2",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"monaco-editor": "^0.46.0",
|
"monaco-editor": "^0.46.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.71.1",
|
"sass": "^1.71.1",
|
||||||
"vue": "^3.4.19",
|
"vue": "^3.4.21",
|
||||||
"vue-chartjs": "^5.3.0",
|
"vue-chartjs": "^5.3.0",
|
||||||
"vue-i18n": "^9.9.1",
|
"vue-i18n": "^9.10.1",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"naive-ui": "^2.37.3",
|
"naive-ui": "^2.38.1",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"unplugin-auto-import": "^0.17.5",
|
"unplugin-auto-import": "^0.17.5",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.18.5",
|
||||||
"unplugin-vue-components": "^0.26.0",
|
"unplugin-vue-components": "^0.26.0",
|
||||||
"vite": "^5.1.4"
|
"vite": "^5.1.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@antfu/install-pkg": {
|
"node_modules/@antfu/install-pkg": {
|
||||||
|
@ -605,12 +605,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/core-base": {
|
"node_modules/@intlify/core-base": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.10.1.tgz",
|
||||||
"integrity": "sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==",
|
"integrity": "sha512-0+Wtjj04GIyglh5KKiNjRwgjpHrhqqGZhaKY/QVjjogWKZq5WHROrTi84pNVsRN18QynyPmjtsVUWqFKPQ45xQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/message-compiler": "9.9.1",
|
"@intlify/message-compiler": "9.10.1",
|
||||||
"@intlify/shared": "9.9.1"
|
"@intlify/shared": "9.10.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
|
@ -620,11 +620,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/message-compiler": {
|
"node_modules/@intlify/message-compiler": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.10.1.tgz",
|
||||||
"integrity": "sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==",
|
"integrity": "sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/shared": "9.9.1",
|
"@intlify/shared": "9.10.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -635,9 +635,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/shared": {
|
"node_modules/@intlify/shared": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.10.1.tgz",
|
||||||
"integrity": "sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==",
|
"integrity": "sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
},
|
},
|
||||||
|
@ -915,49 +915,49 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
|
||||||
"integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==",
|
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.23.9",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
|
||||||
"integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==",
|
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.4.19",
|
"@vue/compiler-core": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
|
||||||
"integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==",
|
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.23.9",
|
||||||
"@vue/compiler-core": "3.4.19",
|
"@vue/compiler-core": "3.4.21",
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/compiler-ssr": "3.4.19",
|
"@vue/compiler-ssr": "3.4.21",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.6",
|
"magic-string": "^0.30.7",
|
||||||
"postcss": "^8.4.33",
|
"postcss": "^8.4.35",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
|
||||||
"integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==",
|
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-api": {
|
"node_modules/@vue/devtools-api": {
|
||||||
|
@ -966,29 +966,29 @@
|
||||||
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
|
||||||
"integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==",
|
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
|
||||||
"integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==",
|
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.4.19",
|
"@vue/reactivity": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
|
||||||
"integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==",
|
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/runtime-core": "3.4.19",
|
"@vue/runtime-core": "3.4.21",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -998,21 +998,21 @@
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
|
||||||
"integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==",
|
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.4.19",
|
"@vue/compiler-ssr": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.4.19"
|
"vue": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||||
"integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
|
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
|
@ -1079,14 +1079,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chart.js": {
|
"node_modules/chart.js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
|
||||||
"integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
|
"integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kurkle/color": "^0.3.0"
|
"@kurkle/color": "^0.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"pnpm": ">=7"
|
"pnpm": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
|
@ -1592,9 +1592,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/naive-ui": {
|
"node_modules/naive-ui": {
|
||||||
"version": "2.37.3",
|
"version": "2.38.1",
|
||||||
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.37.3.tgz",
|
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.38.1.tgz",
|
||||||
"integrity": "sha512-aUkHFXVIluSi8Me+npbcsdv1NYhVMj5t9YaruoCESlqmfqspj+R2QHEVXkTtUI1kQwVrABMCtAGq/wountqjZA==",
|
"integrity": "sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@css-render/plugin-bem": "^0.15.12",
|
"@css-render/plugin-bem": "^0.15.12",
|
||||||
|
@ -2259,9 +2259,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.1.4",
|
"version": "5.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz",
|
||||||
"integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==",
|
"integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.19.3",
|
"esbuild": "^0.19.3",
|
||||||
|
@ -2326,15 +2326,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
|
||||||
"integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==",
|
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/compiler-sfc": "3.4.19",
|
"@vue/compiler-sfc": "3.4.21",
|
||||||
"@vue/runtime-dom": "3.4.19",
|
"@vue/runtime-dom": "3.4.21",
|
||||||
"@vue/server-renderer": "3.4.19",
|
"@vue/server-renderer": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
|
@ -2355,12 +2355,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue-i18n": {
|
"node_modules/vue-i18n": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.10.1.tgz",
|
||||||
"integrity": "sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==",
|
"integrity": "sha512-37HVJQZ/pZaRXGzFmmMomM1u1k7kndv3xCBPYHKEVfv5W3UVK67U/TpBug71ILYLNmjHLHdvTUPRF81pFT5fFg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/core-base": "9.9.1",
|
"@intlify/core-base": "9.10.1",
|
||||||
"@intlify/shared": "9.9.1",
|
"@intlify/shared": "9.10.1",
|
||||||
"@vue/devtools-api": "^6.5.0"
|
"@vue/devtools-api": "^6.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -2766,27 +2766,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/core-base": {
|
"@intlify/core-base": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.10.1.tgz",
|
||||||
"integrity": "sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==",
|
"integrity": "sha512-0+Wtjj04GIyglh5KKiNjRwgjpHrhqqGZhaKY/QVjjogWKZq5WHROrTi84pNVsRN18QynyPmjtsVUWqFKPQ45xQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/message-compiler": "9.9.1",
|
"@intlify/message-compiler": "9.10.1",
|
||||||
"@intlify/shared": "9.9.1"
|
"@intlify/shared": "9.10.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/message-compiler": {
|
"@intlify/message-compiler": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.10.1.tgz",
|
||||||
"integrity": "sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==",
|
"integrity": "sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/shared": "9.9.1",
|
"@intlify/shared": "9.10.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@intlify/shared": {
|
"@intlify/shared": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.10.1.tgz",
|
||||||
"integrity": "sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA=="
|
"integrity": "sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw=="
|
||||||
},
|
},
|
||||||
"@jridgewell/sourcemap-codec": {
|
"@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.4.15",
|
"version": "1.4.15",
|
||||||
|
@ -2960,49 +2960,49 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@vue/compiler-core": {
|
"@vue/compiler-core": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
|
||||||
"integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==",
|
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.23.9",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-dom": {
|
"@vue/compiler-dom": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
|
||||||
"integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==",
|
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-core": "3.4.19",
|
"@vue/compiler-core": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-sfc": {
|
"@vue/compiler-sfc": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
|
||||||
"integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==",
|
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.23.9",
|
||||||
"@vue/compiler-core": "3.4.19",
|
"@vue/compiler-core": "3.4.21",
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/compiler-ssr": "3.4.19",
|
"@vue/compiler-ssr": "3.4.21",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.6",
|
"magic-string": "^0.30.7",
|
||||||
"postcss": "^8.4.33",
|
"postcss": "^8.4.35",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-ssr": {
|
"@vue/compiler-ssr": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
|
||||||
"integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==",
|
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/devtools-api": {
|
"@vue/devtools-api": {
|
||||||
|
@ -3011,29 +3011,29 @@
|
||||||
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
|
||||||
},
|
},
|
||||||
"@vue/reactivity": {
|
"@vue/reactivity": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
|
||||||
"integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==",
|
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-core": {
|
"@vue/runtime-core": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
|
||||||
"integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==",
|
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/reactivity": "3.4.19",
|
"@vue/reactivity": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-dom": {
|
"@vue/runtime-dom": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
|
||||||
"integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==",
|
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/runtime-core": "3.4.19",
|
"@vue/runtime-core": "3.4.21",
|
||||||
"@vue/shared": "3.4.19",
|
"@vue/shared": "3.4.21",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -3045,18 +3045,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/server-renderer": {
|
"@vue/server-renderer": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
|
||||||
"integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==",
|
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-ssr": "3.4.19",
|
"@vue/compiler-ssr": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/shared": {
|
"@vue/shared": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
||||||
"integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
|
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
|
@ -3108,9 +3108,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart.js": {
|
"chart.js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
|
||||||
"integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
|
"integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@kurkle/color": "^0.3.0"
|
"@kurkle/color": "^0.3.0"
|
||||||
}
|
}
|
||||||
|
@ -3502,9 +3502,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"naive-ui": {
|
"naive-ui": {
|
||||||
"version": "2.37.3",
|
"version": "2.38.1",
|
||||||
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.37.3.tgz",
|
"resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.38.1.tgz",
|
||||||
"integrity": "sha512-aUkHFXVIluSi8Me+npbcsdv1NYhVMj5t9YaruoCESlqmfqspj+R2QHEVXkTtUI1kQwVrABMCtAGq/wountqjZA==",
|
"integrity": "sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@css-render/plugin-bem": "^0.15.12",
|
"@css-render/plugin-bem": "^0.15.12",
|
||||||
|
@ -3961,9 +3961,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vite": {
|
"vite": {
|
||||||
"version": "5.1.4",
|
"version": "5.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz",
|
||||||
"integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==",
|
"integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"esbuild": "^0.19.3",
|
"esbuild": "^0.19.3",
|
||||||
|
@ -3982,15 +3982,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue": {
|
"vue": {
|
||||||
"version": "3.4.19",
|
"version": "3.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
|
||||||
"integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==",
|
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.4.19",
|
"@vue/compiler-dom": "3.4.21",
|
||||||
"@vue/compiler-sfc": "3.4.19",
|
"@vue/compiler-sfc": "3.4.21",
|
||||||
"@vue/runtime-dom": "3.4.19",
|
"@vue/runtime-dom": "3.4.21",
|
||||||
"@vue/server-renderer": "3.4.19",
|
"@vue/server-renderer": "3.4.21",
|
||||||
"@vue/shared": "3.4.19"
|
"@vue/shared": "3.4.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue-chartjs": {
|
"vue-chartjs": {
|
||||||
|
@ -4000,12 +4000,12 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"vue-i18n": {
|
"vue-i18n": {
|
||||||
"version": "9.9.1",
|
"version": "9.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.10.1.tgz",
|
||||||
"integrity": "sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==",
|
"integrity": "sha512-37HVJQZ/pZaRXGzFmmMomM1u1k7kndv3xCBPYHKEVfv5W3UVK67U/TpBug71ILYLNmjHLHdvTUPRF81pFT5fFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@intlify/core-base": "9.9.1",
|
"@intlify/core-base": "9.10.1",
|
||||||
"@intlify/shared": "9.9.1",
|
"@intlify/shared": "9.10.1",
|
||||||
"@vue/devtools-api": "^6.5.0"
|
"@vue/devtools-api": "^6.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,25 +9,25 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.1",
|
"chart.js": "^4.4.2",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"monaco-editor": "^0.46.0",
|
"monaco-editor": "^0.46.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"sass": "^1.71.1",
|
"sass": "^1.71.1",
|
||||||
"vue": "^3.4.19",
|
"vue": "^3.4.21",
|
||||||
"vue-chartjs": "^5.3.0",
|
"vue-chartjs": "^5.3.0",
|
||||||
"vue-i18n": "^9.9.1",
|
"vue-i18n": "^9.10.1",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"naive-ui": "^2.37.3",
|
"naive-ui": "^2.38.1",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"unplugin-auto-import": "^0.17.5",
|
"unplugin-auto-import": "^0.17.5",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.18.5",
|
||||||
"unplugin-vue-components": "^0.26.0",
|
"unplugin-vue-components": "^0.26.0",
|
||||||
"vite": "^5.1.4"
|
"vite": "^5.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0d716149856646a7939a157fbfa27913
|
39ad2c9ba3399f6f86d81d749fe6ad60
|
|
@ -1,9 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed, useSlots } from 'vue'
|
||||||
import { NIcon } from 'naive-ui'
|
import { NIcon } from 'naive-ui'
|
||||||
|
|
||||||
const emit = defineEmits(['click'])
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
tooltip: String,
|
tooltip: String,
|
||||||
tTooltip: String,
|
tTooltip: String,
|
||||||
|
@ -35,8 +33,12 @@ const props = defineProps({
|
||||||
tertiary: Boolean,
|
tertiary: Boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['click'])
|
||||||
|
|
||||||
|
const slots = useSlots()
|
||||||
|
|
||||||
const hasTooltip = computed(() => {
|
const hasTooltip = computed(() => {
|
||||||
return props.tooltip || props.tTooltip
|
return props.tooltip || props.tTooltip || slots.tooltip
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -65,7 +67,9 @@ const hasTooltip = computed(() => {
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
|
<slot name="tooltip">
|
||||||
{{ props.tTooltip ? $t(props.tTooltip) : props.tooltip }}
|
{{ props.tTooltip ? $t(props.tTooltip) : props.tooltip }}
|
||||||
|
</slot>
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
<n-button
|
<n-button
|
||||||
v-else
|
v-else
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, reactive } from 'vue'
|
import { computed, nextTick, reactive } from 'vue'
|
||||||
import { debounce, isEmpty, trim } from 'lodash'
|
import { debounce, isEmpty, trim } from 'lodash'
|
||||||
import { NButton, NInput } from 'naive-ui'
|
import { NButton, NInput } from 'naive-ui'
|
||||||
import IconButton from '@/components/common/IconButton.vue'
|
import IconButton from '@/components/common/IconButton.vue'
|
||||||
import Help from '@/components/icons/Help.vue'
|
import SpellCheck from '@/components/icons/SpellCheck.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
fullSearchIcon: {
|
fullSearchIcon: {
|
||||||
|
@ -22,17 +22,22 @@ const props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
exact: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['filterChanged', 'matchChanged'])
|
const emit = defineEmits(['filterChanged', 'matchChanged', 'exactChanged'])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {UnwrapNestedRefs<{filter: string, match: string}>}
|
* @type {UnwrapNestedRefs<{filter: string, match: string, exact: boolean}>}
|
||||||
*/
|
*/
|
||||||
const inputData = reactive({
|
const inputData = reactive({
|
||||||
match: '',
|
match: '',
|
||||||
filter: '',
|
filter: '',
|
||||||
|
exact: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const hasMatch = computed(() => {
|
const hasMatch = computed(() => {
|
||||||
|
@ -43,26 +48,32 @@ const hasFilter = computed(() => {
|
||||||
return !isEmpty(trim(inputData.filter))
|
return !isEmpty(trim(inputData.filter))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const onExactChecked = () => {
|
||||||
|
// update search search result
|
||||||
|
if (hasMatch.value) {
|
||||||
|
nextTick(() => onForceFullSearch())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onFullSearch = () => {
|
const onFullSearch = () => {
|
||||||
inputData.filter = trim(inputData.filter)
|
inputData.filter = trim(inputData.filter)
|
||||||
if (!isEmpty(inputData.filter)) {
|
if (!isEmpty(inputData.filter)) {
|
||||||
inputData.match = inputData.filter
|
inputData.match = inputData.filter
|
||||||
inputData.filter = ''
|
inputData.filter = ''
|
||||||
emit('matchChanged', inputData.match, inputData.filter)
|
emit('matchChanged', inputData.match, inputData.filter, inputData.exact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onForceFullSearch = () => {
|
||||||
|
inputData.filter = trim(inputData.filter)
|
||||||
|
emit('matchChanged', inputData.match, inputData.filter, inputData.exact)
|
||||||
|
}
|
||||||
|
|
||||||
const _onInput = () => {
|
const _onInput = () => {
|
||||||
emit('filterChanged', inputData.filter)
|
emit('filterChanged', inputData.filter, inputData.exact)
|
||||||
}
|
}
|
||||||
const onInput = debounce(_onInput, props.debounceWait, { leading: true, trailing: true })
|
const onInput = debounce(_onInput, props.debounceWait, { leading: true, trailing: true })
|
||||||
|
|
||||||
const onKeyup = (evt) => {
|
|
||||||
if (evt.key === 'Enter') {
|
|
||||||
onFullSearch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClearFilter = () => {
|
const onClearFilter = () => {
|
||||||
inputData.filter = ''
|
inputData.filter = ''
|
||||||
onClearMatch()
|
onClearMatch()
|
||||||
|
@ -77,9 +88,9 @@ const onClearMatch = () => {
|
||||||
const changed = !isEmpty(inputData.match)
|
const changed = !isEmpty(inputData.match)
|
||||||
inputData.match = ''
|
inputData.match = ''
|
||||||
if (changed) {
|
if (changed) {
|
||||||
emit('matchChanged', inputData.match, inputData.filter)
|
emit('matchChanged', inputData.match, inputData.filter, inputData.exact)
|
||||||
} else {
|
} else {
|
||||||
emit('filterChanged', inputData.filter)
|
emit('filterChanged', inputData.filter, inputData.exact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +110,7 @@ defineExpose({
|
||||||
clearable
|
clearable
|
||||||
@clear="onClearFilter"
|
@clear="onClearFilter"
|
||||||
@input="onInput"
|
@input="onInput"
|
||||||
@keyup.enter="onKeyup">
|
@keyup.enter="onFullSearch">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<slot name="prefix" />
|
<slot name="prefix" />
|
||||||
<n-tooltip v-if="hasMatch" placement="bottom">
|
<n-tooltip v-if="hasMatch" placement="bottom">
|
||||||
|
@ -117,12 +128,23 @@ defineExpose({
|
||||||
</template>
|
</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<template v-if="props.useGlob">
|
<template v-if="props.useGlob">
|
||||||
<n-tooltip trigger="hover">
|
<n-tooltip placement="bottom" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-icon :component="Help" />
|
<n-tag
|
||||||
|
v-model:checked="inputData.exact"
|
||||||
|
:checkable="true"
|
||||||
|
:type="props.exact ? 'primary' : 'default'"
|
||||||
|
size="small"
|
||||||
|
strong
|
||||||
|
style="padding: 0 5px"
|
||||||
|
@updateChecked="onExactChecked">
|
||||||
|
<n-icon :size="14">
|
||||||
|
<spell-check :stroke-width="2" />
|
||||||
|
</n-icon>
|
||||||
|
</n-tag>
|
||||||
</template>
|
</template>
|
||||||
<div class="text-block" style="max-width: 600px">
|
<div class="text-block" style="max-width: 600px">
|
||||||
{{ $t('dialogue.filter.filter_pattern_tip') }}
|
{{ $t('dialogue.filter.exact_match_tip') }}
|
||||||
</div>
|
</div>
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
@ -134,11 +156,17 @@ defineExpose({
|
||||||
:disabled="hasMatch && !hasFilter"
|
:disabled="hasMatch && !hasFilter"
|
||||||
:icon="props.fullSearchIcon"
|
:icon="props.fullSearchIcon"
|
||||||
:size="small ? 16 : 20"
|
:size="small ? 16 : 20"
|
||||||
|
:tooltip-delay="1"
|
||||||
border
|
border
|
||||||
small
|
small
|
||||||
stroke-width="4"
|
stroke-width="4"
|
||||||
t-tooltip="interface.full_search"
|
@click="onFullSearch">
|
||||||
@click="onFullSearch" />
|
<template #tooltip>
|
||||||
|
<div class="text-block" style="max-width: 600px">
|
||||||
|
{{ $t('dialogue.filter.filter_pattern_tip') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</icon-button>
|
||||||
<n-button v-else :disabled="hasMatch && !hasFilter" :focusable="false" @click="onFullSearch">
|
<n-button v-else :disabled="hasMatch && !hasFilter" :focusable="false" @click="onFullSearch">
|
||||||
{{ $t('interface.full_search') }}
|
{{ $t('interface.full_search') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
strokeWidth: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
:stroke-width="props.strokeWidth"
|
||||||
|
class="lucide lucide-spell-check"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m6 16 6-12 6 12" />
|
||||||
|
<path d="M8 12h8" />
|
||||||
|
<path d="m16 20 2 2 4-4" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -50,7 +50,10 @@ const inCheckState = ref(false)
|
||||||
|
|
||||||
const dbSelectOptions = computed(() => {
|
const dbSelectOptions = computed(() => {
|
||||||
const dblist = browserStore.getDBList(props.server)
|
const dblist = browserStore.getDBList(props.server)
|
||||||
|
const hasPattern = !isEmpty(filterForm.pattern)
|
||||||
return map(dblist, ({ db, alias, keyCount, maxKeys }) => {
|
return map(dblist, ({ db, alias, keyCount, maxKeys }) => {
|
||||||
|
keyCount = Math.max(0, keyCount)
|
||||||
|
maxKeys = Math.max(keyCount, maxKeys)
|
||||||
let label
|
let label
|
||||||
if (!isEmpty(alias)) {
|
if (!isEmpty(alias)) {
|
||||||
// has alias
|
// has alias
|
||||||
|
@ -59,7 +62,11 @@ const dbSelectOptions = computed(() => {
|
||||||
label = `db${db}`
|
label = `db${db}`
|
||||||
}
|
}
|
||||||
if (props.db === db) {
|
if (props.db === db) {
|
||||||
|
if (hasPattern) {
|
||||||
|
label += ` (${keyCount})`
|
||||||
|
} else {
|
||||||
label += ` (${keyCount}/${maxKeys})`
|
label += ` (${keyCount}/${maxKeys})`
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
label += ` (${maxKeys})`
|
label += ` (${maxKeys})`
|
||||||
}
|
}
|
||||||
|
@ -80,6 +87,11 @@ const moreOptions = [
|
||||||
]
|
]
|
||||||
|
|
||||||
const loadProgress = computed(() => {
|
const loadProgress = computed(() => {
|
||||||
|
const hasPattern = !isEmpty(filterForm.pattern)
|
||||||
|
if (hasPattern) {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
|
||||||
const db = browserStore.getDatabase(props.server, props.db)
|
const db = browserStore.getDatabase(props.server, props.db)
|
||||||
if (db.maxKeys <= 0) {
|
if (db.maxKeys <= 0) {
|
||||||
return 100
|
return 100
|
||||||
|
@ -111,6 +123,7 @@ const onReload = async () => {
|
||||||
browserStore.setKeyFilter(props.server, {
|
browserStore.setKeyFilter(props.server, {
|
||||||
type: matchType,
|
type: matchType,
|
||||||
pattern: unref(filterForm.pattern),
|
pattern: unref(filterForm.pattern),
|
||||||
|
exact: unref(filterForm.exact) === true,
|
||||||
})
|
})
|
||||||
await browserStore.openDatabase(props.server, db)
|
await browserStore.openDatabase(props.server, db)
|
||||||
fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db)
|
fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db)
|
||||||
|
@ -210,6 +223,7 @@ const handleSelectDB = async (db) => {
|
||||||
|
|
||||||
const filterForm = reactive({
|
const filterForm = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
|
exact: false,
|
||||||
pattern: '',
|
pattern: '',
|
||||||
filter: '',
|
filter: '',
|
||||||
})
|
})
|
||||||
|
@ -217,13 +231,15 @@ const onSelectFilterType = (select) => {
|
||||||
onReload()
|
onReload()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFilterInput = (val) => {
|
const onFilterInput = (val, exact) => {
|
||||||
filterForm.filter = val
|
filterForm.filter = val
|
||||||
|
filterForm.exact = exact
|
||||||
}
|
}
|
||||||
|
|
||||||
const onMatchInput = (matchVal, filterVal) => {
|
const onMatchInput = (matchVal, filterVal, exact) => {
|
||||||
filterForm.pattern = matchVal
|
filterForm.pattern = matchVal
|
||||||
filterForm.filter = filterVal
|
filterForm.filter = filterVal
|
||||||
|
filterForm.exact = exact
|
||||||
onReload()
|
onReload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +395,7 @@ watch(
|
||||||
:render-label="({ label }) => $t(label)"
|
:render-label="({ label }) => $t(label)"
|
||||||
placement="top-end"
|
placement="top-end"
|
||||||
style="min-width: 130px"
|
style="min-width: 130px"
|
||||||
|
trigger="click"
|
||||||
@select="onSelectOptions">
|
@select="onSelectOptions">
|
||||||
<icon-button :button-class="['nav-pane-func-btn']" :icon="More" :stroke-width="3.5" size="20" />
|
<icon-button :button-class="['nav-pane-func-btn']" :icon="More" :stroke-width="3.5" size="20" />
|
||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
|
|
|
@ -168,8 +168,8 @@ const handleSelectContextMenu = (action) => {
|
||||||
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
dialogStore.openNewKeyDialog(redisKey, props.server, db)
|
||||||
break
|
break
|
||||||
case 'db_filter':
|
case 'db_filter':
|
||||||
const { match: pattern, type } = browserStore.getKeyFilter(props.server)
|
// const { match: pattern, type } = browserStore.getKeyFilter(props.server)
|
||||||
dialogStore.openKeyFilterDialog(props.server, db, pattern, type)
|
// dialogStore.openKeyFilterDialog(props.server, db, pattern, type)
|
||||||
break
|
break
|
||||||
case 'key_reload':
|
case 'key_reload':
|
||||||
if (node != null && !!!node.loading) {
|
if (node != null && !!!node.loading) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ const onSelectOptions = async (select) => {
|
||||||
:render-label="({ label }) => $t(label)"
|
:render-label="({ label }) => $t(label)"
|
||||||
placement="top-end"
|
placement="top-end"
|
||||||
style="min-width: 130px"
|
style="min-width: 130px"
|
||||||
|
trigger="click"
|
||||||
@select="onSelectOptions">
|
@select="onSelectOptions">
|
||||||
<icon-button :button-class="['nav-pane-func-btn']" :icon="More" :stroke-width="3.5" size="20" />
|
<icon-button :button-class="['nav-pane-func-btn']" :icon="More" :stroke-width="3.5" size="20" />
|
||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
|
|
|
@ -325,7 +325,8 @@
|
||||||
"filter": {
|
"filter": {
|
||||||
"set_key_filter": "Set Key Filter",
|
"set_key_filter": "Set Key Filter",
|
||||||
"filter_pattern": "Pattern",
|
"filter_pattern": "Pattern",
|
||||||
"filter_pattern_tip": "* matches 0 or more chars, e.g. 'key*' \n? matches single char, e.g. 'key?'\n[] matches range, e.g. 'key[1-3]'\n\\ escapes special chars"
|
"filter_pattern_tip": "* matches 0 or more chars, e.g. 'key*' \n? matches single char, e.g. 'key?'\n[] matches range, e.g. 'key[1-3]'\n\\ escapes special chars",
|
||||||
|
"exact_match_tip": "Exact Match"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"name": "Export Data",
|
"name": "Export Data",
|
||||||
|
|
|
@ -325,7 +325,8 @@
|
||||||
"filter": {
|
"filter": {
|
||||||
"set_key_filter": "Definir Filtro de Chave",
|
"set_key_filter": "Definir Filtro de Chave",
|
||||||
"filter_pattern": "Padrão",
|
"filter_pattern": "Padrão",
|
||||||
"filter_pattern_tip": "* corresponde a 0 ou mais caracteres, ex: 'chave*'\n? corresponde a um único caractere, ex: 'chave?'\n[] corresponde a um intervalo, ex: 'chave[1-3]'\n\\ escapa caracteres especiais"
|
"filter_pattern_tip": "* corresponde a 0 ou mais caracteres, ex: 'chave*'\n? corresponde a um único caractere, ex: 'chave?'\n[] corresponde a um intervalo, ex: 'chave[1-3]'\n\\ escapa caracteres especiais",
|
||||||
|
"exact_match_tip": "Correspondência Exata"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"name": "Exportar Dados",
|
"name": "Exportar Dados",
|
||||||
|
|
|
@ -325,7 +325,8 @@
|
||||||
"filter": {
|
"filter": {
|
||||||
"set_key_filter": "设置键过滤器",
|
"set_key_filter": "设置键过滤器",
|
||||||
"filter_pattern": "过滤表达式",
|
"filter_pattern": "过滤表达式",
|
||||||
"filter_pattern_tip": "*:匹配零个或多个字符。例如:\"key*\"匹配到以\"key\"开头的所有键\n?:匹配单个字符。例如:\"key?\"匹配\"key1\"、\"key2\"\n[ ]:匹配指定范围内的单个字符。例如:\"key[1-3]\"可以匹配类似于 \"key1\"、\"key2\"、\"key3\" 的键\n\\:转义字符。如果想要匹配 *、?、[、或],需要使用反斜杠\"\\\"进行转义"
|
"filter_pattern_tip": "*:匹配零个或多个字符。例如:\"key*\"匹配到以\"key\"开头的所有键\n?:匹配单个字符。例如:\"key?\"匹配\"key1\"、\"key2\"\n[ ]:匹配指定范围内的单个字符。例如:\"key[1-3]\"可以匹配类似于 \"key1\"、\"key2\"、\"key3\" 的键\n\\:转义字符。如果想要匹配 *、?、[、或],需要使用反斜杠\"\\\"进行转义",
|
||||||
|
"exact_match_tip": "完全匹配"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"name": "导出数据",
|
"name": "导出数据",
|
||||||
|
|
|
@ -325,7 +325,8 @@
|
||||||
"filter": {
|
"filter": {
|
||||||
"set_key_filter": "設定鍵過濾器",
|
"set_key_filter": "設定鍵過濾器",
|
||||||
"filter_pattern": "過濾表示式",
|
"filter_pattern": "過濾表示式",
|
||||||
"filter_pattern_tip": "*:匹配零個或多個字元。例如:\"key*\"匹配到以\"key\"開頭的所有鍵\n?:匹配單個字元。例如:\"key?\"匹配\"key1\", \"key2\"\n[ ]:匹配指定範圍內的單個字元。例如:\"key[1-3]\"可以匹配類似於 \"key1\", \"key2\", \"key3\" 的鍵\n\\:轉義字元。如果想要匹配 *, ?, [, 或],需要使用反斜線\"\\\"進行轉義"
|
"filter_pattern_tip": "*:匹配零個或多個字元。例如:\"key*\"匹配到以\"key\"開頭的所有鍵\n?:匹配單個字元。例如:\"key?\"匹配\"key1\", \"key2\"\n[ ]:匹配指定範圍內的單個字元。例如:\"key[1-3]\"可以匹配類似於 \"key1\", \"key2\", \"key3\" 的鍵\n\\:轉義字元。如果想要匹配 *, ?, [, 或],需要使用反斜線\"\\\"進行轉義",
|
||||||
|
"exact_match_tip": "精準匹配"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"name": "匯出資料",
|
"name": "匯出資料",
|
||||||
|
|
|
@ -24,6 +24,7 @@ export class RedisServerState {
|
||||||
* @param {Object.<number, RedisDatabaseItem>} databases database list
|
* @param {Object.<number, RedisDatabaseItem>} databases database list
|
||||||
* @param {string|null} patternFilter pattern filter
|
* @param {string|null} patternFilter pattern filter
|
||||||
* @param {string|null} typeFilter redis type filter
|
* @param {string|null} typeFilter redis type filter
|
||||||
|
* @param {boolean} exactFilter exact match filter keyword
|
||||||
* @param {LoadingState} loadingState all loading state in opened connections map by server and LoadingState
|
* @param {LoadingState} loadingState all loading state in opened connections map by server and LoadingState
|
||||||
* @param {KeyViewType} viewType view type selection for all opened connections group by 'server'
|
* @param {KeyViewType} viewType view type selection for all opened connections group by 'server'
|
||||||
* @param {Map<string, RedisNodeItem>} nodeMap map nodes by "type#key"
|
* @param {Map<string, RedisNodeItem>} nodeMap map nodes by "type#key"
|
||||||
|
@ -35,6 +36,7 @@ export class RedisServerState {
|
||||||
databases = {},
|
databases = {},
|
||||||
patternFilter = null,
|
patternFilter = null,
|
||||||
typeFilter = null,
|
typeFilter = null,
|
||||||
|
exactFilter = false,
|
||||||
loadingState = {},
|
loadingState = {},
|
||||||
viewType = KeyViewType.Tree,
|
viewType = KeyViewType.Tree,
|
||||||
nodeMap = new Map(),
|
nodeMap = new Map(),
|
||||||
|
@ -46,6 +48,7 @@ export class RedisServerState {
|
||||||
this.databases = databases
|
this.databases = databases
|
||||||
this.patternFilter = patternFilter
|
this.patternFilter = patternFilter
|
||||||
this.typeFilter = typeFilter
|
this.typeFilter = typeFilter
|
||||||
|
this.exactFilter = exactFilter
|
||||||
this.loadingState = loadingState
|
this.loadingState = loadingState
|
||||||
this.viewType = viewType
|
this.viewType = viewType
|
||||||
this.nodeMap = nodeMap
|
this.nodeMap = nodeMap
|
||||||
|
@ -62,6 +65,7 @@ export class RedisServerState {
|
||||||
this.stats = {}
|
this.stats = {}
|
||||||
this.patternFilter = null
|
this.patternFilter = null
|
||||||
this.typeFilter = null
|
this.typeFilter = null
|
||||||
|
this.exactFilter = false
|
||||||
this.nodeMap.clear()
|
this.nodeMap.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,6 +451,7 @@ export class RedisServerState {
|
||||||
return {
|
return {
|
||||||
match: pattern,
|
match: pattern,
|
||||||
type: toUpper(this.typeFilter),
|
type: toUpper(this.typeFilter),
|
||||||
|
exact: this.exactFilter === true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,10 +459,12 @@ export class RedisServerState {
|
||||||
* set key filter
|
* set key filter
|
||||||
* @param {string} [pattern]
|
* @param {string} [pattern]
|
||||||
* @param {string} [type]
|
* @param {string} [type]
|
||||||
|
* @param {boolean} [exact]
|
||||||
*/
|
*/
|
||||||
setFilter({ pattern, type }) {
|
setFilter({ pattern, type, exact = false }) {
|
||||||
this.patternFilter = pattern === null ? this.patternFilter : pattern
|
this.patternFilter = pattern === null ? this.patternFilter : pattern
|
||||||
this.typeFilter = type === null ? this.typeFilter : type
|
this.typeFilter = type === null ? this.typeFilter : type
|
||||||
|
this.exactFilter = exact === true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -293,8 +293,7 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async openDatabase(server, db) {
|
async openDatabase(server, db) {
|
||||||
const { match: filterPattern, type: filterType } = this.getKeyFilter(server)
|
const { data, success, msg } = await OpenDatabase(server, db)
|
||||||
const { data, success, msg } = await OpenDatabase(server, db, filterPattern, filterType)
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new Error(msg)
|
throw new Error(msg)
|
||||||
}
|
}
|
||||||
|
@ -565,22 +564,23 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} match
|
* @param {string} match
|
||||||
|
* @param {boolean} exact
|
||||||
* @param {string} [matchType]
|
* @param {string} [matchType]
|
||||||
* @param {number} [loadType] 0.load next; 1.load next full; 2.reload load all
|
* @param {number} [loadType] 0.load next; 1.load next full; 2.reload load all
|
||||||
* @returns {Promise<{keys: string[], maxKeys: number, end: boolean}>}
|
* @returns {Promise<{keys: string[], maxKeys: number, end: boolean}>}
|
||||||
*/
|
*/
|
||||||
async scanKeys({ server, db, match = '*', matchType = '', loadType = 0 }) {
|
async scanKeys({ server, db, match = '*', exact = false, matchType = '', loadType = 0 }) {
|
||||||
let resp
|
let resp
|
||||||
switch (loadType) {
|
switch (loadType) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
resp = await LoadNextKeys(server, db, match, matchType)
|
resp = await LoadNextKeys(server, db, match, matchType, exact)
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
resp = await LoadNextAllKeys(server, db, match, matchType)
|
resp = await LoadNextAllKeys(server, db, match, matchType, exact)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
resp = await LoadAllKeys(server, db, match, matchType)
|
resp = await LoadAllKeys(server, db, match, matchType, exact)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
const { data, success, msg } = resp || {}
|
const { data, success, msg } = resp || {}
|
||||||
|
@ -595,22 +595,24 @@ const useBrowserStore = defineStore('browser', {
|
||||||
*
|
*
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string|null} prefix
|
* @param {string|null} match
|
||||||
|
* @param {boolean} exact
|
||||||
* @param {string|null} matchType
|
* @param {string|null} matchType
|
||||||
* @param {boolean} [all]
|
* @param {boolean} [all]
|
||||||
* @return {Promise<{keys: Array<string|number[]>, maxKeys: number, end: boolean}>}
|
* @return {Promise<{keys: Array<string|number[]>, maxKeys: number, end: boolean}>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _loadKeys(server, db, prefix, matchType, all) {
|
async _loadKeys({ server, db, match, exact, matchType, all }) {
|
||||||
let match = prefix
|
|
||||||
if (isEmpty(match)) {
|
if (isEmpty(match)) {
|
||||||
match = '*'
|
match = '*'
|
||||||
} else if (!isRedisGlob(match)) {
|
}
|
||||||
if (!endsWith(prefix, '*')) {
|
|
||||||
match = prefix + '*'
|
if (!isRedisGlob(match) && !exact) {
|
||||||
|
if (!endsWith(match, '*')) {
|
||||||
|
match = match + '*'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.scanKeys({ server, db, match, matchType, loadType: all ? 1 : 0 })
|
return this.scanKeys({ server, db, match, exact, matchType, loadType: all ? 1 : 0 })
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -620,8 +622,15 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @return {Promise<boolean>}
|
* @return {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
async loadMoreKeys(server, db) {
|
async loadMoreKeys(server, db) {
|
||||||
const { match, type: keyType } = this.getKeyFilter(server)
|
const { match, type: keyType, exact } = this.getKeyFilter(server)
|
||||||
const { keys, maxKeys, end } = await this._loadKeys(server, db, match, keyType, false)
|
const { keys, maxKeys, end } = await this._loadKeys({
|
||||||
|
server,
|
||||||
|
db,
|
||||||
|
match,
|
||||||
|
exact,
|
||||||
|
matchType: keyType,
|
||||||
|
all: false,
|
||||||
|
})
|
||||||
/** @type RedisServerState **/
|
/** @type RedisServerState **/
|
||||||
const serverInst = this.servers[server]
|
const serverInst = this.servers[server]
|
||||||
if (serverInst != null) {
|
if (serverInst != null) {
|
||||||
|
@ -640,8 +649,8 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async loadAllKeys(server, db) {
|
async loadAllKeys(server, db) {
|
||||||
const { match, type: keyType } = this.getKeyFilter(server)
|
const { match, type: keyType, exact } = this.getKeyFilter(server)
|
||||||
const { keys, maxKeys } = await this._loadKeys(server, db, match, keyType, true)
|
const { keys, maxKeys } = await this._loadKeys({ server, db, match, exact, matchType: keyType, all: true })
|
||||||
/** @type RedisServerState **/
|
/** @type RedisServerState **/
|
||||||
const serverInst = this.servers[server]
|
const serverInst = this.servers[server]
|
||||||
if (serverInst != null) {
|
if (serverInst != null) {
|
||||||
|
@ -670,8 +679,15 @@ const useBrowserStore = defineStore('browser', {
|
||||||
match += '*'
|
match += '*'
|
||||||
}
|
}
|
||||||
// FIXME: ignore original match pattern due to redis not support combination matching
|
// FIXME: ignore original match pattern due to redis not support combination matching
|
||||||
const { match: originMatch, type: keyType } = this.getKeyFilter(server)
|
const { match: originMatch, type: keyType, exact } = this.getKeyFilter(server)
|
||||||
const { keys, maxKeys, success } = await this._loadKeys(server, db, match, keyType, true)
|
const { keys, maxKeys, success } = await this._loadKeys({
|
||||||
|
server,
|
||||||
|
db,
|
||||||
|
match: originMatch,
|
||||||
|
exact: false,
|
||||||
|
matchType: keyType,
|
||||||
|
all: true,
|
||||||
|
})
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1915,7 +1931,7 @@ const useBrowserStore = defineStore('browser', {
|
||||||
/**
|
/**
|
||||||
* get key filter pattern and filter type
|
* get key filter pattern and filter type
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @returns {{match: string, type: string}}
|
* @returns {{match: string, type: string, exact: boolean}}
|
||||||
*/
|
*/
|
||||||
getKeyFilter(server) {
|
getKeyFilter(server) {
|
||||||
let serverInst = this.servers[server]
|
let serverInst = this.servers[server]
|
||||||
|
@ -1933,11 +1949,12 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {string} [pattern]
|
* @param {string} [pattern]
|
||||||
* @param {string} [type]
|
* @param {string} [type]
|
||||||
|
* @param {boolean} [exact]
|
||||||
*/
|
*/
|
||||||
setKeyFilter(server, { pattern, type }) {
|
setKeyFilter(server, { pattern, type, exact = false }) {
|
||||||
const serverInst = this.servers[server]
|
const serverInst = this.servers[server]
|
||||||
if (serverInst != null) {
|
if (serverInst != null) {
|
||||||
serverInst.setFilter({ pattern, type })
|
serverInst.setFilter({ pattern, type, exact })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -11,8 +11,8 @@ require (
|
||||||
github.com/vmihailenco/msgpack/v5 v5.4.1
|
github.com/vmihailenco/msgpack/v5 v5.4.1
|
||||||
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68
|
github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68
|
||||||
github.com/wailsapp/wails/v2 v2.8.0
|
github.com/wailsapp/wails/v2 v2.8.0
|
||||||
golang.org/x/crypto v0.19.0
|
golang.org/x/crypto v0.21.0
|
||||||
golang.org/x/net v0.21.0
|
golang.org/x/net v0.22.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ require (
|
||||||
github.com/wailsapp/go-webview2 v1.0.10 // indirect
|
github.com/wailsapp/go-webview2 v1.0.10 // indirect
|
||||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect
|
||||||
golang.org/x/sys v0.17.0 // indirect
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
)
|
)
|
||||||
|
|
16
go.sum
16
go.sum
|
@ -100,13 +100,13 @@ github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhw
|
||||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||||
github.com/wailsapp/wails/v2 v2.8.0 h1:b2NNn99uGPiN6P5bDsnPwOJZWtAOUhNLv7Vl+YxMTr4=
|
github.com/wailsapp/wails/v2 v2.8.0 h1:b2NNn99uGPiN6P5bDsnPwOJZWtAOUhNLv7Vl+YxMTr4=
|
||||||
github.com/wailsapp/wails/v2 v2.8.0/go.mod h1:EFUGWkUX3KofO4fmKR/GmsLy3HhPH7NbyOEaMt8lBF0=
|
github.com/wailsapp/wails/v2 v2.8.0/go.mod h1:EFUGWkUX3KofO4fmKR/GmsLy3HhPH7NbyOEaMt8lBF0=
|
||||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
|
||||||
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -114,11 +114,11 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.18.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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
|
Loading…
Reference in New Issue