From f64f3771997e87bf5aed8f1b348e4af39d7e2b7e Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Thu, 1 Sep 2022 21:45:35 +1200 Subject: [PATCH 1/6] Feature: Search parser improvements --- go.mod | 2 +- storage/database.go | 77 +----------------------------------- storage/search.go | 95 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 76 deletions(-) create mode 100644 storage/search.go diff --git a/go.mod b/go.mod index 87ed7a6..db3904a 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/spf13/cobra v1.5.0 github.com/spf13/pflag v1.0.5 github.com/tg123/go-htpasswd v1.2.0 + golang.org/x/text v0.3.7 modernc.org/sqlite v1.18.1 ) @@ -46,7 +47,6 @@ require ( golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect - golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.12 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect lukechampine.com/uint128 v1.2.0 // indirect diff --git a/storage/database.go b/storage/database.go index ffe15a8..78f2a45 100644 --- a/storage/database.go +++ b/storage/database.go @@ -307,81 +307,8 @@ func Search(search string) ([]data.Summary, error) { panic(err) } - q := sqlf.From("mailbox"). - Select(`ID, Data, read, - json_extract(Data, '$.To') as ToJSON, - json_extract(Data, '$.From') as FromJSON, - json_extract(Data, '$.Subject') as Subject, - json_extract(Data, '$.Attachments') as Attachments - `). - OrderBy("Sort DESC"). - Limit(200) - - for _, w := range args { - if cleanString(w) == "" { - continue - } - - exclude := false - if strings.HasPrefix(w, "-") || strings.HasPrefix(w, "!") { - exclude = true - w = w[1:] - } - - if strings.HasPrefix(w, "to:") { - w = cleanString(w[3:]) - if w != "" { - if exclude { - q.Where("ToJSON NOT LIKE ?", "%"+escPercentChar(w)+"%") - } else { - q.Where("ToJSON LIKE ?", "%"+escPercentChar(w)+"%") - } - } - } else if strings.HasPrefix(w, "from:") { - w = cleanString(w[5:]) - if w != "" { - if exclude { - q.Where("FromJSON NOT LIKE ?", "%"+escPercentChar(w)+"%") - } else { - q.Where("FromJSON LIKE ?", "%"+escPercentChar(w)+"%") - } - } - } else if strings.HasPrefix(w, "subject:") { - w = cleanString(w[8:]) - if w != "" { - if exclude { - q.Where("Subject NOT LIKE ?", "%"+escPercentChar(w)+"%") - } else { - q.Where("Subject LIKE ?", "%"+escPercentChar(w)+"%") - } - } - } else if w == "is:read" { - if exclude { - q.Where("Read = 0") - } else { - q.Where("Read = 1") - } - } else if w == "is:unread" { - if exclude { - q.Where("Read = 1") - } else { - q.Where("Read = 0") - } - } else if w == "has:attachment" || w == "has:attachments" { - if exclude { - q.Where("Attachments = 0") - } else { - q.Where("Attachments > 0") - } - } else { - // search text - if exclude { - q.Where("search NOT LIKE ?", "%"+cleanString(escPercentChar(w))+"%") - } else { - q.Where("search LIKE ?", "%"+cleanString(escPercentChar(w))+"%") - } - } - } + // generate the SQL based on arguments + q := searchParser(args) if err := q.QueryAndClose(nil, db, func(row *sql.Rows) { var id string diff --git a/storage/search.go b/storage/search.go new file mode 100644 index 0000000..91fbfa9 --- /dev/null +++ b/storage/search.go @@ -0,0 +1,95 @@ +package storage + +import ( + "regexp" + "strings" + + "github.com/leporo/sqlf" +) + +// SearchParser returns the SQL syntax for the database search based on the search arguments +func searchParser(args []string) *sqlf.Stmt { + q := sqlf.From("mailbox"). + Select(`ID, Data, read, + json_extract(Data, '$.To') as ToJSON, + json_extract(Data, '$.From') as FromJSON, + json_extract(Data, '$.Subject') as Subject, + json_extract(Data, '$.Attachments') as Attachments + `). + OrderBy("Sort DESC"). + Limit(200) + + for _, w := range args { + if cleanString(w) == "" { + continue + } + + exclude := false + // search terms starting with a `-` or `!` imply an exclude + if len(w) > 1 && (strings.HasPrefix(w, "-") || strings.HasPrefix(w, "!")) { + exclude = true + w = w[1:] + } + + re := regexp.MustCompile(`[a-zA-Z0-9]+`) + if !re.MatchString(w) { + continue + } + + if strings.HasPrefix(w, "to:") { + w = cleanString(w[3:]) + if w != "" { + if exclude { + q.Where("ToJSON NOT LIKE ?", "%"+escPercentChar(w)+"%") + } else { + q.Where("ToJSON LIKE ?", "%"+escPercentChar(w)+"%") + } + } + } else if strings.HasPrefix(w, "from:") { + w = cleanString(w[5:]) + if w != "" { + if exclude { + q.Where("FromJSON NOT LIKE ?", "%"+escPercentChar(w)+"%") + } else { + q.Where("FromJSON LIKE ?", "%"+escPercentChar(w)+"%") + } + } + } else if strings.HasPrefix(w, "subject:") { + w = cleanString(w[8:]) + if w != "" { + if exclude { + q.Where("Subject NOT LIKE ?", "%"+escPercentChar(w)+"%") + } else { + q.Where("Subject LIKE ?", "%"+escPercentChar(w)+"%") + } + } + } else if w == "is:read" { + if exclude { + q.Where("Read = 0") + } else { + q.Where("Read = 1") + } + } else if w == "is:unread" { + if exclude { + q.Where("Read = 1") + } else { + q.Where("Read = 0") + } + } else if w == "has:attachment" || w == "has:attachments" { + if exclude { + q.Where("Attachments = 0") + } else { + q.Where("Attachments > 0") + } + } else { + // search text + if exclude { + q.Where("search NOT LIKE ?", "%"+cleanString(escPercentChar(w))+"%") + } else { + q.Where("search LIKE ?", "%"+cleanString(escPercentChar(w))+"%") + } + } + } + + return q +} From 6233cb1e07633d75a9164bd247b7585c408a0a79 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Thu, 1 Sep 2022 22:01:56 +1200 Subject: [PATCH 2/6] UI: Update frontend modules & esbuild --- package-lock.json | 623 ++++++++++++++++++++++++---------------------- 1 file changed, 324 insertions(+), 299 deletions(-) diff --git a/package-lock.json b/package-lock.json index c499df9..e984532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,9 +24,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz", - "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -34,46 +34,62 @@ "node": ">=6.0.0" } }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@popperjs/core": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", - "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.38.tgz", + "integrity": "sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.38.tgz", + "integrity": "sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g==", "dependencies": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-core": "3.2.38", + "@vue/shared": "3.2.38" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.38.tgz", + "integrity": "sha512-KZjrW32KloMYtTcHAFuw3CqsyWc5X6seb8KbkANSWt3Cz9p2qA8c1GJpSkksFP9ABb6an0FLCFl46ZFXx3kKpg==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.38", + "@vue/compiler-dom": "3.2.38", + "@vue/compiler-ssr": "3.2.38", + "@vue/reactivity-transform": "3.2.38", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -81,69 +97,69 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.38.tgz", + "integrity": "sha512-bm9jOeyv1H3UskNm4S6IfueKjUNFmi2kRweFIGnqaGkkRePjwEcfCVqyS3roe7HvF4ugsEkhf4+kIvDhip6XzQ==", "dependencies": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.38", + "@vue/shared": "3.2.38" } }, "node_modules/@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.38.tgz", + "integrity": "sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw==", "dependencies": { - "@vue/shared": "3.2.37" + "@vue/shared": "3.2.38" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.38.tgz", + "integrity": "sha512-3SD3Jmi1yXrDwiNJqQ6fs1x61WsDLqVk4NyKVz78mkaIRh6d3IqtRnptgRfXn+Fzf+m6B1KxBYWq1APj6h4qeA==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.38", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.38.tgz", + "integrity": "sha512-kk0qiSiXUU/IKxZw31824rxmFzrLr3TL6ZcbrxWTKivadoKupdlzbQM4SlGo4MU6Zzrqv4fzyUasTU1jDoEnzg==", "dependencies": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/reactivity": "3.2.38", + "@vue/shared": "3.2.38" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.38.tgz", + "integrity": "sha512-4PKAb/ck2TjxdMSzMsnHViOrrwpudk4/A56uZjhzvusoEU9xqa5dygksbzYepdZeB5NqtRw5fRhWIiQlRVK45A==", "dependencies": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/runtime-core": "3.2.38", + "@vue/shared": "3.2.38", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.38.tgz", + "integrity": "sha512-pg+JanpbOZ5kEfOZzO2bt02YHd+ELhYP8zPeLU1H0e7lg079NtuuSB8fjLdn58c4Ou8UQ6C1/P+528nXnLPAhA==", "dependencies": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-ssr": "3.2.38", + "@vue/shared": "3.2.38" }, "peerDependencies": { - "vue": "3.2.37" + "vue": "3.2.38" } }, "node_modules/@vue/shared": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.38.tgz", + "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==" }, "node_modules/anymatch": { "version": "3.1.2", @@ -323,9 +339,9 @@ } }, "node_modules/esbuild": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz", - "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", "dev": true, "hasInstallScript": true, "bin": { @@ -335,32 +351,33 @@ "node": ">=12" }, "optionalDependencies": { - "esbuild-android-64": "0.14.51", - "esbuild-android-arm64": "0.14.51", - "esbuild-darwin-64": "0.14.51", - "esbuild-darwin-arm64": "0.14.51", - "esbuild-freebsd-64": "0.14.51", - "esbuild-freebsd-arm64": "0.14.51", - "esbuild-linux-32": "0.14.51", - "esbuild-linux-64": "0.14.51", - "esbuild-linux-arm": "0.14.51", - "esbuild-linux-arm64": "0.14.51", - "esbuild-linux-mips64le": "0.14.51", - "esbuild-linux-ppc64le": "0.14.51", - "esbuild-linux-riscv64": "0.14.51", - "esbuild-linux-s390x": "0.14.51", - "esbuild-netbsd-64": "0.14.51", - "esbuild-openbsd-64": "0.14.51", - "esbuild-sunos-64": "0.14.51", - "esbuild-windows-32": "0.14.51", - "esbuild-windows-64": "0.14.51", - "esbuild-windows-arm64": "0.14.51" + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" } }, "node_modules/esbuild-android-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz", - "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", "cpu": [ "x64" ], @@ -374,9 +391,9 @@ } }, "node_modules/esbuild-android-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz", - "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", "cpu": [ "arm64" ], @@ -390,9 +407,9 @@ } }, "node_modules/esbuild-darwin-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz", - "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", "cpu": [ "x64" ], @@ -406,9 +423,9 @@ } }, "node_modules/esbuild-darwin-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz", - "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", "cpu": [ "arm64" ], @@ -422,9 +439,9 @@ } }, "node_modules/esbuild-freebsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz", - "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", "cpu": [ "x64" ], @@ -438,9 +455,9 @@ } }, "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz", - "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", "cpu": [ "arm64" ], @@ -454,9 +471,9 @@ } }, "node_modules/esbuild-linux-32": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz", - "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", "cpu": [ "ia32" ], @@ -470,9 +487,9 @@ } }, "node_modules/esbuild-linux-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz", - "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", "cpu": [ "x64" ], @@ -486,9 +503,9 @@ } }, "node_modules/esbuild-linux-arm": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz", - "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", "cpu": [ "arm" ], @@ -502,9 +519,9 @@ } }, "node_modules/esbuild-linux-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz", - "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", "cpu": [ "arm64" ], @@ -518,9 +535,9 @@ } }, "node_modules/esbuild-linux-mips64le": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz", - "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", "cpu": [ "mips64el" ], @@ -534,9 +551,9 @@ } }, "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz", - "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", "cpu": [ "ppc64" ], @@ -550,9 +567,9 @@ } }, "node_modules/esbuild-linux-riscv64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz", - "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", "cpu": [ "riscv64" ], @@ -566,9 +583,9 @@ } }, "node_modules/esbuild-linux-s390x": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz", - "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", "cpu": [ "s390x" ], @@ -582,9 +599,9 @@ } }, "node_modules/esbuild-netbsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz", - "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", "cpu": [ "x64" ], @@ -598,9 +615,9 @@ } }, "node_modules/esbuild-openbsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz", - "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", "cpu": [ "x64" ], @@ -642,9 +659,9 @@ } }, "node_modules/esbuild-sunos-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz", - "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", "cpu": [ "x64" ], @@ -658,9 +675,9 @@ } }, "node_modules/esbuild-windows-32": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz", - "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", "cpu": [ "ia32" ], @@ -674,9 +691,9 @@ } }, "node_modules/esbuild-windows-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz", - "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", "cpu": [ "x64" ], @@ -690,9 +707,9 @@ } }, "node_modules/esbuild-windows-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz", - "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", "cpu": [ "arm64" ], @@ -1028,9 +1045,9 @@ } }, "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", "funding": [ { "type": "opencollective", @@ -1183,15 +1200,15 @@ } }, "node_modules/vue": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.38.tgz", + "integrity": "sha512-hHrScEFSmDAWL0cwO4B6WO7D3sALZPbfuThDsGBebthrNlDxdJZpGR3WB87VbjpPh96mep1+KzukYEhpHDFa8Q==", "dependencies": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.38", + "@vue/compiler-sfc": "3.2.38", + "@vue/runtime-dom": "3.2.38", + "@vue/server-renderer": "3.2.38", + "@vue/shared": "3.2.38" } }, "node_modules/wrappy": { @@ -1203,46 +1220,53 @@ }, "dependencies": { "@babel/parser": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz", - "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==" + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==" + }, + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "dev": true, + "optional": true }, "@popperjs/core": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", - "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.38.tgz", + "integrity": "sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q==", "requires": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.38.tgz", + "integrity": "sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g==", "requires": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-core": "3.2.38", + "@vue/shared": "3.2.38" } }, "@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.38.tgz", + "integrity": "sha512-KZjrW32KloMYtTcHAFuw3CqsyWc5X6seb8KbkANSWt3Cz9p2qA8c1GJpSkksFP9ABb6an0FLCFl46ZFXx3kKpg==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.38", + "@vue/compiler-dom": "3.2.38", + "@vue/compiler-ssr": "3.2.38", + "@vue/reactivity-transform": "3.2.38", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -1250,66 +1274,66 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.38.tgz", + "integrity": "sha512-bm9jOeyv1H3UskNm4S6IfueKjUNFmi2kRweFIGnqaGkkRePjwEcfCVqyS3roe7HvF4ugsEkhf4+kIvDhip6XzQ==", "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.38", + "@vue/shared": "3.2.38" } }, "@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.38.tgz", + "integrity": "sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw==", "requires": { - "@vue/shared": "3.2.37" + "@vue/shared": "3.2.38" } }, "@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.38.tgz", + "integrity": "sha512-3SD3Jmi1yXrDwiNJqQ6fs1x61WsDLqVk4NyKVz78mkaIRh6d3IqtRnptgRfXn+Fzf+m6B1KxBYWq1APj6h4qeA==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.38", + "@vue/shared": "3.2.38", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.38.tgz", + "integrity": "sha512-kk0qiSiXUU/IKxZw31824rxmFzrLr3TL6ZcbrxWTKivadoKupdlzbQM4SlGo4MU6Zzrqv4fzyUasTU1jDoEnzg==", "requires": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/reactivity": "3.2.38", + "@vue/shared": "3.2.38" } }, "@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.38.tgz", + "integrity": "sha512-4PKAb/ck2TjxdMSzMsnHViOrrwpudk4/A56uZjhzvusoEU9xqa5dygksbzYepdZeB5NqtRw5fRhWIiQlRVK45A==", "requires": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/runtime-core": "3.2.38", + "@vue/shared": "3.2.38", "csstype": "^2.6.8" } }, "@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.38.tgz", + "integrity": "sha512-pg+JanpbOZ5kEfOZzO2bt02YHd+ELhYP8zPeLU1H0e7lg079NtuuSB8fjLdn58c4Ou8UQ6C1/P+528nXnLPAhA==", "requires": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-ssr": "3.2.38", + "@vue/shared": "3.2.38" } }, "@vue/shared": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.38.tgz", + "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==" }, "anymatch": { "version": "3.1.2", @@ -1445,142 +1469,143 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "esbuild": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz", - "integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", "dev": true, "requires": { - "esbuild-android-64": "0.14.51", - "esbuild-android-arm64": "0.14.51", - "esbuild-darwin-64": "0.14.51", - "esbuild-darwin-arm64": "0.14.51", - "esbuild-freebsd-64": "0.14.51", - "esbuild-freebsd-arm64": "0.14.51", - "esbuild-linux-32": "0.14.51", - "esbuild-linux-64": "0.14.51", - "esbuild-linux-arm": "0.14.51", - "esbuild-linux-arm64": "0.14.51", - "esbuild-linux-mips64le": "0.14.51", - "esbuild-linux-ppc64le": "0.14.51", - "esbuild-linux-riscv64": "0.14.51", - "esbuild-linux-s390x": "0.14.51", - "esbuild-netbsd-64": "0.14.51", - "esbuild-openbsd-64": "0.14.51", - "esbuild-sunos-64": "0.14.51", - "esbuild-windows-32": "0.14.51", - "esbuild-windows-64": "0.14.51", - "esbuild-windows-arm64": "0.14.51" + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" } }, "esbuild-android-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz", - "integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", "dev": true, "optional": true }, "esbuild-android-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz", - "integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", "dev": true, "optional": true }, "esbuild-darwin-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz", - "integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", "dev": true, "optional": true }, "esbuild-darwin-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz", - "integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", "dev": true, "optional": true }, "esbuild-freebsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz", - "integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", "dev": true, "optional": true }, "esbuild-freebsd-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz", - "integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", "dev": true, "optional": true }, "esbuild-linux-32": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz", - "integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", "dev": true, "optional": true }, "esbuild-linux-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz", - "integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", "dev": true, "optional": true }, "esbuild-linux-arm": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz", - "integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", "dev": true, "optional": true }, "esbuild-linux-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz", - "integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", "dev": true, "optional": true }, "esbuild-linux-mips64le": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz", - "integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", "dev": true, "optional": true }, "esbuild-linux-ppc64le": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz", - "integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", "dev": true, "optional": true }, "esbuild-linux-riscv64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz", - "integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", "dev": true, "optional": true }, "esbuild-linux-s390x": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz", - "integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", "dev": true, "optional": true }, "esbuild-netbsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz", - "integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", "dev": true, "optional": true }, "esbuild-openbsd-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz", - "integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", "dev": true, "optional": true }, @@ -1607,30 +1632,30 @@ } }, "esbuild-sunos-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz", - "integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", "dev": true, "optional": true }, "esbuild-windows-32": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz", - "integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", "dev": true, "optional": true }, "esbuild-windows-64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz", - "integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", "dev": true, "optional": true }, "esbuild-windows-arm64": { - "version": "0.14.51", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz", - "integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==", + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", "dev": true, "optional": true }, @@ -1871,9 +1896,9 @@ "dev": true }, "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -1977,15 +2002,15 @@ "dev": true }, "vue": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "version": "3.2.38", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.38.tgz", + "integrity": "sha512-hHrScEFSmDAWL0cwO4B6WO7D3sALZPbfuThDsGBebthrNlDxdJZpGR3WB87VbjpPh96mep1+KzukYEhpHDFa8Q==", "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.38", + "@vue/compiler-sfc": "3.2.38", + "@vue/runtime-dom": "3.2.38", + "@vue/server-renderer": "3.2.38", + "@vue/shared": "3.2.38" } }, "wrappy": { From 9501b460c5c55c64a8af5714660ace9f2af88a88 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sat, 3 Sep 2022 00:35:02 +1200 Subject: [PATCH 3/6] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2ba90f..a73dcab 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Mailpit is inspired by [MailHog](#why-rewrite-mailhog), but much, much faster. - Optional browser notifications for new mail (HTTPS only) - Configurable automatic email pruning (default keeps the most recent 500 emails) - Email storage either in a temporary or persistent database ([see wiki](https://github.com/axllent/mailpit/wiki/Email-storage)) -- Fast SMTP processing & storing - approximately 300-600 emails per second depending on CPU, network speed & email size +- Fast SMTP processing & storing - approximately 70-100 emails per second depending on CPU, network speed & email size - Can handle hundreds of thousands of emails - Optional SMTP with STARTTLS & SMTP authentication ([see wiki](https://github.com/axllent/mailpit/wiki/SMTP-with-STARTTLS-and-authentication)) - Optional HTTPS for web UI ([see wiki](https://github.com/axllent/mailpit/wiki/HTTPS)) From 3c81e152e66b5ca7f63c71d5c9fab85a0e3a1247 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sat, 3 Sep 2022 00:37:24 +1200 Subject: [PATCH 4/6] UI: Display unknown recipients as as `Undisclosed recipients` --- server/ui-src/App.vue | 2 +- server/ui-src/templates/Message.vue | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/ui-src/App.vue b/server/ui-src/App.vue index 9991b86..4b5bf19 100644 --- a/server/ui-src/App.vue +++ b/server/ui-src/App.vue @@ -270,7 +270,7 @@ export default { return message.To[i].Address; } - return '[ Unknown ]'; + return '[ Undisclosed recipients ]'; }, getRelativeCreated: function(message) { diff --git a/server/ui-src/templates/Message.vue b/server/ui-src/templates/Message.vue index 4befcb5..8cd0ac0 100644 --- a/server/ui-src/templates/Message.vue +++ b/server/ui-src/templates/Message.vue @@ -110,10 +110,11 @@ export default { To - + {{ t.Name + " <" + t.Address +">" }} + Undisclosed recipients From 6dbdbf16379c0311c197bbac5c468f146e908fed Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sat, 3 Sep 2022 16:46:21 +1200 Subject: [PATCH 5/6] UI: Post data using 'application/json' --- server/ui-src/mixins.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/server/ui-src/mixins.js b/server/ui-src/mixins.js index 494a64b..a4ff61c 100644 --- a/server/ui-src/mixins.js +++ b/server/ui-src/mixins.js @@ -96,12 +96,8 @@ const commonMixins = { */ post: function (url, values, callback) { let self = this; - const params = new URLSearchParams(); - for (const [key, value] of Object.entries(values)) { - params.append(key, value); - } self.loading++; - axios.post(url, params) + axios.post(url, values) .then(callback) .catch(self.handleError) .then(function () { From 43403bc6f724c52cda644d91cbf1a8b581d691e1 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sat, 3 Sep 2022 17:41:14 +1200 Subject: [PATCH 6/6] Feature: Multiple message selection for group actions using shift/ctrl click Allow group actions for deleting & marking as read/unread, resolves #11 --- server/api.go | 91 ++++++++++++-- server/server.go | 25 ++-- server/ui-src/App.vue | 201 +++++++++++++++++++++++-------- server/ui-src/assets/styles.scss | 17 ++- 4 files changed, 266 insertions(+), 68 deletions(-) diff --git a/server/api.go b/server/api.go index 7e161bb..cd1f691 100644 --- a/server/api.go +++ b/server/api.go @@ -28,7 +28,8 @@ func apiMailboxStats(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write(bytes) } -func apiListMailbox(w http.ResponseWriter, r *http.Request) { +// List messages +func apiListMessages(w http.ResponseWriter, r *http.Request) { start, limit := getStartLimit(r) messages, err := storage.List(start, limit) @@ -52,17 +53,14 @@ func apiListMailbox(w http.ResponseWriter, r *http.Request) { _, _ = w.Write(bytes) } -func apiSearchMailbox(w http.ResponseWriter, r *http.Request) { +// Search all messages +func apiSearchMessages(w http.ResponseWriter, r *http.Request) { search := strings.TrimSpace(r.URL.Query().Get("query")) if search == "" { fourOFour(w) return } - // we will only return up to 200 results - start := 0 - // limit := 200 - messages, err := storage.Search(search) if err != nil { httpError(w, err.Error()) @@ -73,7 +71,7 @@ func apiSearchMailbox(w http.ResponseWriter, r *http.Request) { var res messagesResult - res.Start = start + res.Start = 0 res.Items = messages res.Count = len(messages) res.Total = stats.Total @@ -144,7 +142,7 @@ func apiDownloadSource(w http.ResponseWriter, r *http.Request) { _, _ = w.Write(data) } -// Delete all messages in the mailbox +// Delete all messages func apiDeleteAll(w http.ResponseWriter, r *http.Request) { err := storage.DeleteAllMessages() if err != nil { @@ -156,6 +154,31 @@ func apiDeleteAll(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) } +// Delete all selected messages +func apiDeleteSelected(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + + var data struct { + IDs []string + } + err := decoder.Decode(&data) + if err != nil { + panic(err) + } + + ids := data.IDs + + for _, id := range ids { + if err := storage.DeleteOneMessage(id); err != nil { + httpError(w, err.Error()) + return + } + } + + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte("ok")) +} + // Delete a single message func apiDeleteOne(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -188,7 +211,7 @@ func apiUnreadOne(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) } -// Mark single message as unread +// Mark all messages as read func apiMarkAllRead(w http.ResponseWriter, r *http.Request) { err := storage.MarkAllRead() if err != nil { @@ -200,6 +223,56 @@ func apiMarkAllRead(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) } +// Mark selected message as read +func apiMarkSelectedRead(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + + var data struct { + IDs []string + } + err := decoder.Decode(&data) + if err != nil { + panic(err) + } + + ids := data.IDs + + for _, id := range ids { + if err := storage.MarkRead(id); err != nil { + httpError(w, err.Error()) + return + } + } + + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte("ok")) +} + +// Mark selected message as unread +func apiMarkSelectedUnread(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + + var data struct { + IDs []string + } + err := decoder.Decode(&data) + if err != nil { + panic(err) + } + + ids := data.IDs + + for _, id := range ids { + if err := storage.MarkUnread(id); err != nil { + httpError(w, err.Error()) + return + } + } + + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte("ok")) +} + // Websocket to broadcast changes func apiWebsocket(w http.ResponseWriter, r *http.Request) { websockets.ServeWs(websockets.MessageHub, w, r) diff --git a/server/server.go b/server/server.go index fdffb25..32ffdbf 100644 --- a/server/server.go +++ b/server/server.go @@ -34,17 +34,20 @@ func Listen() { go websockets.MessageHub.Run() r := mux.NewRouter() - r.HandleFunc("/api/stats", middleWareFunc(apiMailboxStats)) - r.HandleFunc("/api/messages", middleWareFunc(apiListMailbox)) - r.HandleFunc("/api/search", middleWareFunc(apiSearchMailbox)) - r.HandleFunc("/api/delete", middleWareFunc(apiDeleteAll)) - r.HandleFunc("/api/events", apiWebsocket) - r.HandleFunc("/api/read", apiMarkAllRead) - r.HandleFunc("/api/{id}/source", middleWareFunc(apiDownloadSource)) - r.HandleFunc("/api/{id}/part/{partID}", middleWareFunc(apiDownloadAttachment)) - r.HandleFunc("/api/{id}/delete", middleWareFunc(apiDeleteOne)) - r.HandleFunc("/api/{id}/unread", middleWareFunc(apiUnreadOne)) - r.HandleFunc("/api/{id}", middleWareFunc(apiOpenMessage)) + r.HandleFunc("/api/stats", middleWareFunc(apiMailboxStats)).Methods("GET") + r.HandleFunc("/api/messages", middleWareFunc(apiListMessages)).Methods("GET") + r.HandleFunc("/api/search", middleWareFunc(apiSearchMessages)).Methods("GET") + r.HandleFunc("/api/delete", middleWareFunc(apiDeleteAll)).Methods("GET") + r.HandleFunc("/api/delete", middleWareFunc(apiDeleteSelected)).Methods("POST") + r.HandleFunc("/api/events", apiWebsocket).Methods("GET") + r.HandleFunc("/api/read", apiMarkAllRead).Methods("GET") + r.HandleFunc("/api/read", apiMarkSelectedRead).Methods("POST") + r.HandleFunc("/api/unread", apiMarkSelectedUnread).Methods("POST") + r.HandleFunc("/api/{id}/source", middleWareFunc(apiDownloadSource)).Methods("GET") + r.HandleFunc("/api/{id}/part/{partID}", middleWareFunc(apiDownloadAttachment)).Methods("GET") + r.HandleFunc("/api/{id}/delete", middleWareFunc(apiDeleteOne)).Methods("GET") + r.HandleFunc("/api/{id}/unread", middleWareFunc(apiUnreadOne)).Methods("GET") + r.HandleFunc("/api/{id}", middleWareFunc(apiOpenMessage)).Methods("GET") r.PathPrefix("/").Handler(middlewareHandler(http.FileServer(http.FS(serverRoot)))) http.Handle("/", r) diff --git a/server/ui-src/App.vue b/server/ui-src/App.vue index 4b5bf19..33f4afc 100644 --- a/server/ui-src/App.vue +++ b/server/ui-src/App.vue @@ -23,7 +23,8 @@ export default { scrollInPlace: false, message: false, notificationsSupported: false, - notificationsEnabled: false + notificationsEnabled: false, + selected: [] } }, watch: { @@ -60,6 +61,7 @@ export default { loadMessages: function () { let self = this; let params = {}; + this.selected = []; let uri = 'api/messages'; if (self.search) { @@ -128,10 +130,10 @@ export default { openMessage: function(id) { let self = this; - let params = {}; + self.selected = []; let uri = 'api/' + self.currentPath - self.get(uri, params, function(response) { + self.get(uri, false, function(response) { for (let i in self.items) { if (self.items[i].ID == self.currentPath) { if (!self.items[i].Read) { @@ -192,6 +194,19 @@ export default { }); }, + deleteSelected: function() { + let self = this; + if (!self.selected.length) { + return false; + } + let uri = 'api/delete' + self.post(uri, {'ids': self.selected}, function(response) { + window.location.hash = ""; + self.scrollInPlace = true; + self.loadMessages(); + }); + }, + markUnread: function() { let self = this; if (!self.message) { @@ -215,6 +230,32 @@ export default { }); }, + markSelectedRead: function() { + let self = this; + if (!self.selected.length) { + return false; + } + let uri = 'api/read' + self.post(uri, {'ids': self.selected}, function(response) { + window.location.hash = ""; + self.scrollInPlace = true; + self.loadMessages(); + }); + }, + + markSelectedUnread: function() { + let self = this; + if (!self.selected.length) { + return false; + } + let uri = 'api/unread' + self.post(uri, {'ids': self.selected}, function(response) { + window.location.hash = ""; + self.scrollInPlace = true; + self.loadMessages(); + }); + }, + // websocket connect connect: function () { let wsproto = location.protocol == 'https:' ? 'wss' : 'ws'; @@ -310,8 +351,48 @@ export default { } }); } - } + }, + toggleSelected: function(e, id) { + e.preventDefault(); + + if (this.isSelected(id)) { + this.selected = this.selected.filter(function(ele){ + return ele != id; + }); + } else { + this.selected.push(id); + } + }, + + selectRange: function(e, id) { + e.preventDefault(); + + let selecting = false; + let lastSelected = this.selected.length > 0 && this.selected[this.selected.length - 1]; + + if (lastSelected === false) { + this.selected.push(id); + return; + } + + for (let d of this.items) { + if (selecting) { + this.selected.push(d.ID); + if (d.ID == lastSelected || d.ID == id) { + // reached backwards select + break; + } + } else if (d.ID == id || d.ID == lastSelected) { + this.selected.push(d.ID); + selecting = true; + } + } + }, + + isSelected: function(id) { + return this.selected.indexOf(id) != -1; + } } } @@ -333,7 +414,7 @@ export default { Delete Download @@ -409,18 +490,42 @@ export default { -
  • +
  • - + Mark all read
  • -
  • +
  • Delete all
  • + +
  • + Selected {{selected.length}} + +
  • +
  • + + + Mark read + +
  • +
  • + + + Mark unread + +
  • +
  • + + + Delete + +
  • +
  • @@ -439,8 +544,10 @@ export default {
    - +
    @@ -497,17 +604,17 @@ export default { @@ -516,17 +623,17 @@ export default { @@ -535,21 +642,21 @@ export default { diff --git a/server/ui-src/assets/styles.scss b/server/ui-src/assets/styles.scss index 75c0196..d606d89 100644 --- a/server/ui-src/assets/styles.scss +++ b/server/ui-src/assets/styles.scss @@ -34,7 +34,7 @@ z-index: 1500; } -.message.read:not(.active) { +.message.read:not(.active):not(.selected) { color: $gray-500; } @@ -75,6 +75,21 @@ border-top: 0; } +.message.selected { + background: $primary; + color: #fff; + + .text-muted { + color: #fff !important; + } + + &.read { + b { + font-weight: normal; + } + } +} + body.blur { .privacy { filter: blur(3px);