diff --git a/go.mod b/go.mod index f7d05af11..647067c18 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/axllent/semver v0.0.1 github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 github.com/gorilla/mux v1.8.1 - github.com/gorilla/websocket v1.5.1 + github.com/gorilla/websocket v1.5.3 github.com/jhillyerd/enmime v1.2.0 - github.com/klauspost/compress v1.17.8 + github.com/klauspost/compress v1.17.9 github.com/kovidgoyal/imaging v1.6.3 github.com/leporo/sqlf v1.4.0 github.com/lithammer/shortuuid/v4 v4.0.0 @@ -20,7 +20,7 @@ require ( github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e github.com/rqlite/gorqlite v0.0.0-20240227123050-397b03f02418 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/tg123/go-htpasswd v1.2.2 github.com/vanng822/go-premailer v1.21.0 @@ -28,7 +28,7 @@ require ( golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.30.0 + modernc.org/sqlite v1.30.1 ) require ( @@ -59,7 +59,7 @@ require ( golang.org/x/sys v0.21.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect - modernc.org/libc v1.52.1 // indirect + modernc.org/libc v1.53.3 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect diff --git a/go.sum b/go.sum index 7d448c36f..a19ed5291 100644 --- a/go.sum +++ b/go.sum @@ -11,7 +11,7 @@ github.com/axllent/semver v0.0.1 h1:QqF+KSGxgj8QZzSXAvKFqjGWE5792ksOnQhludToK8E= github.com/axllent/semver v0.0.1/go.mod h1:2xSPzvG8n9mRfdtxSvWvfTfQGWfHsMsHO1iZnKATMSc= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -34,8 +34,8 @@ github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -44,8 +44,8 @@ github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQykt github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jhillyerd/enmime v1.2.0 h1:dIu1IPEymQgoT2dzuB//ttA/xcV40NMPpQtmd4wslHk= github.com/jhillyerd/enmime v1.2.0/go.mod h1:FRFuUPCLh8PByQv+8xRcLO9QHqaqTqreYhopv5eyk4I= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kovidgoyal/imaging v1.6.3 h1:iNPpv7ygiaB/NOztc6APMT7yr9UwBS+rOZwIbAdtyY8= github.com/kovidgoyal/imaging v1.6.3/go.mod h1:sHvcLOOVhJuto2IoNdPLEqnAUoL5ZfHEF0PpNH+882g= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -95,8 +95,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= @@ -195,18 +195,18 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk= -modernc.org/cc/v4 v4.21.2/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.17.10 h1:6wrtRozgrhCxieCeJh85QsxkX/2FFrT9hdaWPlbn4Zo= -modernc.org/ccgo/v4 v4.17.10/go.mod h1:0NBHgsqTTpm9cA5z2ccErvGZmtntSM9qD2kFAs6pjXM= +modernc.org/cc/v4 v4.21.3 h1:2mhBdWKtivdFlLR1ecKXTljPG1mfvbByX7QKztAIJl8= +modernc.org/cc/v4 v4.21.3/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.18.1 h1:1zF5kPBFq/ZVTulBOKgQPQITdOzzyBUfC51gVYP62E4= +modernc.org/ccgo/v4 v4.18.1/go.mod h1:ao1fAxf9a2KEOL15WY8+yP3wnpaOpP/QuyFOZ9HJolM= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M= -modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ= +modernc.org/libc v1.53.3 h1:9O0aSLZuHPgp49we24NoFFteRgXNLGBAQ3TODrW3XLg= +modernc.org/libc v1.53.3/go.mod h1:kb+Erju4FfHNE59xd2fNpv5CBeAeej6fHbx8p8xaiyI= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -215,8 +215,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.30.0 h1:8YhPUs/HTnlEgErn/jSYQTwHN/ex8CjHHjg+K9iG7LM= -modernc.org/sqlite v1.30.0/go.mod h1:cgkTARJ9ugeXSNaLBPK3CqbOe7Ec7ZhWPoMFGldEYEw= +modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= +modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/internal/htmlcheck/caniemail-data.json b/internal/htmlcheck/caniemail-data.json index 448c1833c..10edaa752 100644 --- a/internal/htmlcheck/caniemail-data.json +++ b/internal/htmlcheck/caniemail-data.json @@ -1,6 +1,6 @@ { "api_version":"1.0.4", - "last_update_date":"2024-04-19 09:12:53 +0000", + "last_update_date":"2024-05-30 19:50:57 +0000", "nicenames":{"family":{"gmail":"Gmail","outlook":"Outlook","yahoo":"Yahoo! Mail","apple-mail":"Apple Mail","aol":"AOL","thunderbird":"Mozilla Thunderbird","microsoft":"Microsoft","samsung-email":"Samsung Email","sfr":"SFR","orange":"Orange","protonmail":"ProtonMail","hey":"HEY","mail-ru":"Mail.ru","fastmail":"Fastmail","laposte":"LaPoste.net","t-online-de":"T-online.de","free-fr":"Free.fr","gmx":"GMX","web-de":"WEB.DE","ionos-1and1":"1&1","rainloop":"RainLoop","wp-pl":"WP.pl"},"platform":{"desktop-app":"Desktop","desktop-webmail":"Desktop Webmail","mobile-webmail":"Mobile Webmail","webmail":"Webmail","ios":"iOS","android":"Android","windows":"Windows","macos":"macOS","windows-mail":"Windows Mail","outlook-com":"Outlook.com"},"support":{"supported":"Supported","mitigated":"Partially supported","unsupported":"Not supported","unknown":"Support unknown","mixed":"Mixed support"},"category":{"html":"HTML","css":"CSS","image":"Image formats","others":"Others"}}, "data":[ { @@ -4366,7 +4366,7 @@ "last_test_date":"2020-02-06", "test_url":"https://www.caniemail.com/tests/images.html", "test_results_url":"https://app.emailonacid.com/app/acidtest/xm1T5nQ1MKtHpVSJidhagmt3Z53CjqbkMhorlvuM0Gz57/list", - "stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-02":"n"},"ios":{"2020-02":"n"},"android":{"2020-02":"n"},"mobile-webmail":{"2020-02":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"a #1"},"windows-mail":{"2020-02":"n"},"macos":{"2016":"y","16.80":"y"},"outlook-com":{"2020-02":"y","2024-01":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"samsung-email":{"android":{"9.0":"y"}},"thunderbird":{"windows":{"2020-02":"y"},"macos":{"68.4":"y"}},"aol":{"desktop-webmail":{"2020-02":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"yahoo":{"desktop-webmail":{"2020-02":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"orange":{"desktop-webmail":{"2020-02":"n #2","2021-03":"y","2024-04":"y"},"ios":{"2020-02":"n","2024-04":"y"},"android":{"2020-02":"n","2024-04":"y"}},"sfr":{"desktop-webmail":{"2020-02":"n #2"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2"}},"gmx":{"desktop-webmail":{"2022-09":"a #3"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"a #3"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}}, + "stats":{"apple-mail":{"macos":{"13":"y"},"ios":{"13":"y"}},"gmail":{"desktop-webmail":{"2020-02":"n","2024-05":"n"},"ios":{"2020-02":"n"},"android":{"2020-02":"n"},"mobile-webmail":{"2020-02":"n"}},"outlook":{"windows":{"2007":"n","2010":"n","2013":"n","2016":"n","2019":"a #1"},"windows-mail":{"2020-02":"n"},"macos":{"2016":"y","16.80":"y"},"outlook-com":{"2020-02":"y","2024-01":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"samsung-email":{"android":{"9.0":"y"}},"thunderbird":{"windows":{"2020-02":"y"},"macos":{"68.4":"y"}},"aol":{"desktop-webmail":{"2020-02":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"yahoo":{"desktop-webmail":{"2020-02":"y"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"orange":{"desktop-webmail":{"2020-02":"n #2","2021-03":"y","2024-04":"y"},"ios":{"2020-02":"n","2024-04":"y"},"android":{"2020-02":"n","2024-04":"y"}},"sfr":{"desktop-webmail":{"2020-02":"n #2"},"ios":{"2020-02":"y"},"android":{"2020-02":"y"}},"protonmail":{"desktop-webmail":{"2020-03":"y"},"ios":{"2020-03":"y"},"android":{"2020-03":"y"}},"hey":{"desktop-webmail":{"2020-06":"n"}},"mail-ru":{"desktop-webmail":{"2020-10":"y"}},"fastmail":{"desktop-webmail":{"2021-07":"y"}},"laposte":{"desktop-webmail":{"2021-08":"n #2"}},"gmx":{"desktop-webmail":{"2022-09":"a #3"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"web-de":{"desktop-webmail":{"2022-09":"a #3"},"ios":{"2022-09":"y"},"android":{"2022-09":"y"}},"ionos-1and1":{"desktop-webmail":{"2022-09":"y"},"android":{"2022-09":"y"}}}, "notes":null, "notes_by_num":{"1":"Partial: Does not render Base 64 gif format.","2":"Not supported. The `src` is turned into a `nosrc` attribute.","3":"Partial: Only supports Base 64 png format."} }, diff --git a/package-lock.json b/package-lock.json index 7123c8669..a3d91465b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,9 +72,9 @@ "peer": true }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz", - "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -88,9 +88,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz", - "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -104,9 +104,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz", - "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -120,9 +120,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz", - "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -136,9 +136,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz", - "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -152,9 +152,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz", - "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -168,9 +168,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz", - "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -184,9 +184,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz", - "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -200,9 +200,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz", - "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -216,9 +216,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz", - "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -232,9 +232,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz", - "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -248,9 +248,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz", - "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -264,9 +264,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz", - "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -280,9 +280,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz", - "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -296,9 +296,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz", - "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -312,9 +312,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz", - "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -328,9 +328,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz", - "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -344,9 +344,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz", - "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -360,9 +360,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz", - "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -376,9 +376,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz", - "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -392,9 +392,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz", - "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -408,9 +408,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz", - "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -424,9 +424,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz", - "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -938,36 +938,36 @@ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, "node_modules/@vue/compiler-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", - "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.29.tgz", + "integrity": "sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==", "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/shared": "3.4.27", + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.29", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", - "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.29.tgz", + "integrity": "sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==", "dependencies": { - "@vue/compiler-core": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-core": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", - "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", - "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/compiler-core": "3.4.27", - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.29.tgz", + "integrity": "sha512-zygDcEtn8ZimDlrEQyLUovoWgKQic6aEQqRXce2WXBvSeHbEbcAsXyCk9oG33ZkyWH4sl9D3tkYc1idoOkdqZQ==", + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.29", + "@vue/compiler-dom": "3.4.29", + "@vue/compiler-ssr": "3.4.29", + "@vue/shared": "3.4.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", "postcss": "^8.4.38", @@ -975,12 +975,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", - "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.29.tgz", + "integrity": "sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==", "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-dom": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/devtools-api": { @@ -989,48 +989,49 @@ "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==" }, "node_modules/@vue/reactivity": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz", - "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.29.tgz", + "integrity": "sha512-w8+KV+mb1a8ornnGQitnMdLfE0kXmteaxLdccm2XwdFxXst4q/Z7SEboCV5SqJNpZbKFeaRBBJBhW24aJyGINg==", "dependencies": { - "@vue/shared": "3.4.27" + "@vue/shared": "3.4.29" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz", - "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.29.tgz", + "integrity": "sha512-s8fmX3YVR/Rk5ig0ic0NuzTNjK2M7iLuVSZyMmCzN/+Mjuqqif1JasCtEtmtoJWF32pAtUjyuT2ljNKNLeOmnQ==", "dependencies": { - "@vue/reactivity": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/reactivity": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz", - "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.29.tgz", + "integrity": "sha512-gI10atCrtOLf/2MPPMM+dpz3NGulo9ZZR9d1dWo4fYvm+xkfvRrw1ZmJ7mkWtiJVXSsdmPbcK1p5dZzOCKDN0g==", "dependencies": { - "@vue/runtime-core": "3.4.27", - "@vue/shared": "3.4.27", + "@vue/reactivity": "3.4.29", + "@vue/runtime-core": "3.4.29", + "@vue/shared": "3.4.29", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz", - "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.29.tgz", + "integrity": "sha512-HMLCmPI2j/k8PVkSBysrA2RxcxC5DgBiCdj7n7H2QtR8bQQPqKAe8qoaxLcInzouBmzwJ+J0x20ygN/B5mYBng==", "dependencies": { - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-ssr": "3.4.29", + "@vue/shared": "3.4.29" }, "peerDependencies": { - "vue": "3.4.27" + "vue": "3.4.29" } }, "node_modules/@vue/shared": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", - "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.29.tgz", + "integrity": "sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA==" }, "node_modules/anymatch": { "version": "3.1.3", @@ -1440,9 +1441,9 @@ } }, "node_modules/esbuild": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz", - "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -1452,29 +1453,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.4", - "@esbuild/android-arm": "0.21.4", - "@esbuild/android-arm64": "0.21.4", - "@esbuild/android-x64": "0.21.4", - "@esbuild/darwin-arm64": "0.21.4", - "@esbuild/darwin-x64": "0.21.4", - "@esbuild/freebsd-arm64": "0.21.4", - "@esbuild/freebsd-x64": "0.21.4", - "@esbuild/linux-arm": "0.21.4", - "@esbuild/linux-arm64": "0.21.4", - "@esbuild/linux-ia32": "0.21.4", - "@esbuild/linux-loong64": "0.21.4", - "@esbuild/linux-mips64el": "0.21.4", - "@esbuild/linux-ppc64": "0.21.4", - "@esbuild/linux-riscv64": "0.21.4", - "@esbuild/linux-s390x": "0.21.4", - "@esbuild/linux-x64": "0.21.4", - "@esbuild/netbsd-x64": "0.21.4", - "@esbuild/openbsd-x64": "0.21.4", - "@esbuild/sunos-x64": "0.21.4", - "@esbuild/win32-arm64": "0.21.4", - "@esbuild/win32-ia32": "0.21.4", - "@esbuild/win32-x64": "0.21.4" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/esbuild-plugin-vue-next": { @@ -1939,9 +1940,9 @@ "integrity": "sha512-p+I4yLZUDnoJMa5zoi+71nLQmoLQ6WRU4W8vZu1BZk2PlIYOz5mGnj9/7t2lGWKYeOr4zo6pajhY0/9TS5Zcdw==" }, "node_modules/nan": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", - "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "optional": true }, "node_modules/nanoid": { @@ -1968,9 +1969,9 @@ "optional": true }, "node_modules/node-abi": { - "version": "3.63.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.63.0.tgz", - "integrity": "sha512-vAszCsOUrUxjGAmdnM/pq7gUgie0IRteCQMX6d4A534fQCR93EJU5qgzBvU6EkFfK27s0T3HEV3BOyJIr7OMYw==", + "version": "3.65.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", + "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -2045,9 +2046,9 @@ } }, "node_modules/openapi-path-templating": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.5.3.tgz", - "integrity": "sha512-NPL+3w4NsBmqTzCQGQbSUHTAUYM/ubm3tH9BWe77uvGyA8L32L73w+w7zhBCsql0zp+gqGvglaHdQTpWx/tzmA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.6.0.tgz", + "integrity": "sha512-1atBNwOUrZXthTvlvvX8k8ovFEF3iA8mDidYMkdOtvVdndBhTrspbwGXNOzEUaJhm9iUl4Tf5uQaeTLAJvwPig==", "dependencies": { "apg-lite": "^1.0.3" }, @@ -2056,9 +2057,9 @@ } }, "node_modules/openapi-server-url-templating": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.0.0.tgz", - "integrity": "sha512-hJ3sCVx7XyYATfRqBfUY+dE+DSM/tsqZ83xtcyHhNqtDiN2Il/uedCzBaE9re3gLRkC4I0GrCI84aaQHboNMCw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.1.0.tgz", + "integrity": "sha512-dtyTFKx2xVcO0W8JKaluXIHC9l/MLjHeflBaWjiWNMCHp/TBs9dEjQDbj/VFlHR4omFOKjjmqm1pW1aCAhmPBg==", "dependencies": { "apg-lite": "^1.0.3" }, @@ -2336,9 +2337,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.77.4", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.4.tgz", - "integrity": "sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==", + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -2353,9 +2354,9 @@ } }, "node_modules/sass-embedded": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.77.2.tgz", - "integrity": "sha512-luiDeWNZ0tKs1jCiSFbuz8wFVQxYqN+vh+yfm9v7kW42yPtwEF8+z2ROaDJluSUZ7vhFmsXuqoKg9qBxc7SCnw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.77.5.tgz", + "integrity": "sha512-JQI8aprHDRSNK5exXsbusswTENQPJxW1QWUcLdwuyESoJClT1zo8e+4cmaV5OAU4abcRC6Av4/RmLocPdjcR3A==", "dev": true, "peer": true, "dependencies": { @@ -2370,29 +2371,29 @@ "node": ">=16.0.0" }, "optionalDependencies": { - "sass-embedded-android-arm": "1.77.2", - "sass-embedded-android-arm64": "1.77.2", - "sass-embedded-android-ia32": "1.77.2", - "sass-embedded-android-x64": "1.77.2", - "sass-embedded-darwin-arm64": "1.77.2", - "sass-embedded-darwin-x64": "1.77.2", - "sass-embedded-linux-arm": "1.77.2", - "sass-embedded-linux-arm64": "1.77.2", - "sass-embedded-linux-ia32": "1.77.2", - "sass-embedded-linux-musl-arm": "1.77.2", - "sass-embedded-linux-musl-arm64": "1.77.2", - "sass-embedded-linux-musl-ia32": "1.77.2", - "sass-embedded-linux-musl-x64": "1.77.2", - "sass-embedded-linux-x64": "1.77.2", - "sass-embedded-win32-arm64": "1.77.2", - "sass-embedded-win32-ia32": "1.77.2", - "sass-embedded-win32-x64": "1.77.2" + "sass-embedded-android-arm": "1.77.5", + "sass-embedded-android-arm64": "1.77.5", + "sass-embedded-android-ia32": "1.77.5", + "sass-embedded-android-x64": "1.77.5", + "sass-embedded-darwin-arm64": "1.77.5", + "sass-embedded-darwin-x64": "1.77.5", + "sass-embedded-linux-arm": "1.77.5", + "sass-embedded-linux-arm64": "1.77.5", + "sass-embedded-linux-ia32": "1.77.5", + "sass-embedded-linux-musl-arm": "1.77.5", + "sass-embedded-linux-musl-arm64": "1.77.5", + "sass-embedded-linux-musl-ia32": "1.77.5", + "sass-embedded-linux-musl-x64": "1.77.5", + "sass-embedded-linux-x64": "1.77.5", + "sass-embedded-win32-arm64": "1.77.5", + "sass-embedded-win32-ia32": "1.77.5", + "sass-embedded-win32-x64": "1.77.5" } }, "node_modules/sass-embedded-android-arm": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.77.2.tgz", - "integrity": "sha512-rMuIMZ/FstMrT9Y23LDgQGpCyfe3i10dJnmW+DVJ9Gqz4dR7qpysEBIQXU35mHVq8ppNZ0yGiFlFZTSiiVMdzQ==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.77.5.tgz", + "integrity": "sha512-/DfNYoykqwMFduecqa8n0NH+cS6oLdCPFjwhe92efsOOt5WDYEOlolnhoOENZxqdzvSV+8axL+mHQ1Ypl4MLtg==", "cpu": [ "arm" ], @@ -2410,9 +2411,9 @@ } }, "node_modules/sass-embedded-android-arm64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.77.2.tgz", - "integrity": "sha512-7DiFMros5iRYrkPlNqUBfzZ/DCgsI199pRF8xuBsPf9yuB8SLDOqvNk3QOnUCMAbpjW5VW1JgdfGFFlHTCnJQA==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.77.5.tgz", + "integrity": "sha512-t4yIhK5OUpg1coZxFpDo3BhI2YVj21JxEd5SVI6FfcWD2ESroQWsC4cbq3ejw5aun8R1Kx6xH1EKxO8bSMvn1g==", "cpu": [ "arm64" ], @@ -2430,9 +2431,9 @@ } }, "node_modules/sass-embedded-android-ia32": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.77.2.tgz", - "integrity": "sha512-qN0laKrAjuvBLFdUogGz8jQlbHs6tgH91tKQeE7ZE4AO9zzDRlXtaEJP1x6B6AGVc8UOEkvQyR3Nej4qwWprhA==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.77.5.tgz", + "integrity": "sha512-92dWhEbR0Z2kpjbpfOx4LM9wlNBSnDsRtwpkMUK8udQIE7uF3E4/Fsf/88IJk0MrRkk4iwrsxxiCb1bz2tWnHQ==", "cpu": [ "ia32" ], @@ -2450,9 +2451,9 @@ } }, "node_modules/sass-embedded-android-x64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.77.2.tgz", - "integrity": "sha512-HByqtC5g5hOaJenWs4Klx6gFEIZYx+IEFh5K56U+wB+jd6EU32Lrnbdxy1+i/p/kZrd+23HrVHQPv8zpmxucaw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.77.5.tgz", + "integrity": "sha512-lFnXz9lRnjRLJ8Y28ONJViID3rDq4p6LJ/9ByPk2ZnSpx5ouUjsu4AfrXKJ0jgHWBaDvSKSxq2fPpt5aMQAEZA==", "cpu": [ "x64" ], @@ -2470,9 +2471,9 @@ } }, "node_modules/sass-embedded-darwin-arm64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.77.2.tgz", - "integrity": "sha512-0jkL/FwbAStqqxFSjHfhElEAWrKRRvFz2JeXOxskUdzMehDMv5LaewqSRCijyeKBO3KgurvndmSfrOizdU6WAw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.77.5.tgz", + "integrity": "sha512-J3yP6w+xqPrGQE0+sO4Gam6kBDJL5ivgkFNxR0fVlvKeN5qVFYhymp/xGRRMxBrKjohEQtBGP431EzrtvUMFow==", "cpu": [ "arm64" ], @@ -2490,9 +2491,9 @@ } }, "node_modules/sass-embedded-darwin-x64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.77.2.tgz", - "integrity": "sha512-8Sy36IxOOFPWA5TdhC87SvOkrXUSis51CGKlIsM8yZISQiY9y8b+wrNJM1f3oHvs641xZBaeIuwibJXaY6hNBg==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.77.5.tgz", + "integrity": "sha512-A9fh5tg4s0FidMTG31Vs8TzYZ3Mam/I/tfqvN0g512OhBajp/p2DJvBY+0Br2r+TNH1yGUXf2ZfULuTBFj5u8w==", "cpu": [ "x64" ], @@ -2510,9 +2511,9 @@ } }, "node_modules/sass-embedded-linux-arm": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.77.2.tgz", - "integrity": "sha512-/gtCseBkGCBw61p6MG2BqeYy8rblffw2KXUzMKjo9Hlqj/KajWDk7j1B+mVnqrHOPB/KBbm8Ym/2ooCYpnMIkQ==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.77.5.tgz", + "integrity": "sha512-O7gbOWJloxITBZNkpwChFltxofsnDUf+3pz7+q2ETQKvZQ3kUfFENAF37slo0bsHJ7IEpwJK3ZJlnhZvIgfhgw==", "cpu": [ "arm" ], @@ -2530,9 +2531,9 @@ } }, "node_modules/sass-embedded-linux-arm64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.77.2.tgz", - "integrity": "sha512-hlfNFu1IWHI0cOsbpFWPrJlx7IFZfXuI3iEhwa4oljM21y72E6tETUFmTr4f9Ka9qDLXkUxUoYaTH2SqGU9dDA==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.77.5.tgz", + "integrity": "sha512-LoN804X7QsyvT/h8UGcgBMfV1SdT4JRRNV+slBICxoXPKBLXbZm9KyLRCBQcMLLdlXSZdOfZilxUN1Bd2az6OA==", "cpu": [ "arm64" ], @@ -2550,9 +2551,9 @@ } }, "node_modules/sass-embedded-linux-ia32": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.77.2.tgz", - "integrity": "sha512-JSIqGIeAKlrMw/oMFFFxZ10F3QUJVdjeGVI83h6mwNHTYgrX6PuOngcAYleIpYR5XicQgfueC5pPVPbP5CArBQ==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.77.5.tgz", + "integrity": "sha512-KHNJymlEmjyJbhGfB34zowohjgMvv/qKVsDX5hPlar+qMh+cxJwfgPln1Zl9bfe9qLObmEV2zFA1rpVBWy4xGQ==", "cpu": [ "ia32" ], @@ -2570,9 +2571,9 @@ } }, "node_modules/sass-embedded-linux-musl-arm": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.77.2.tgz", - "integrity": "sha512-LZTSnfHPlfvkdQ8orpnEUCEx40qhKpMjxN3Ggi8kgQqv5jvtqn0ECdWl0n4WI5CrlkmtdS3VeFcsf078bt/f8Q==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.77.5.tgz", + "integrity": "sha512-TLhJzd1TJ0oX1oULobkWLMDLeErD27WbhdZqxtFvIqzyO+1TZPMwojhRX4YNWmHdmmYhIuXTR9foWxwL3Xjgsg==", "cpu": [ "arm" ], @@ -2587,9 +2588,9 @@ } }, "node_modules/sass-embedded-linux-musl-arm64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.77.2.tgz", - "integrity": "sha512-JQZuONuhIurKjc/qE9cTiJXSLixL8hGkalWN3LJHasYHVAU92QA/t8rv0T51vIzf/I2F59He3bapkPme60dwSw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.77.5.tgz", + "integrity": "sha512-ZWl8K8rCL4/phm3IPWDADwjnYAiohoaKg7BKjGo+36zv8P0ocoA0A3j4xx7/kjUJWagOmmoTyYxoOu+lo1NaKw==", "cpu": [ "arm64" ], @@ -2604,9 +2605,9 @@ } }, "node_modules/sass-embedded-linux-musl-ia32": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.77.2.tgz", - "integrity": "sha512-6F1GHBgPkcTXtfM0MK3PofozagNF8IawdfIG4RNzGeSZRhGBRgZLOS+vdre4xubTLSaa6xjbI47YfaD43z8URQ==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.77.5.tgz", + "integrity": "sha512-83zNSgsIIc+tYQFKepFIlvAvAHnbWSpZ824MjqXJLeCbfzcMO8SZ/q6OA0Zd2SIrf79lCWI4OfPHqp1PI6M7HQ==", "cpu": [ "ia32" ], @@ -2621,9 +2622,9 @@ } }, "node_modules/sass-embedded-linux-musl-x64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.77.2.tgz", - "integrity": "sha512-8BiqLA1NJeN3rCaX6t747GWMMdH5YUFYuytXU8waDC/u+FSGoOHRxfrsB8BEWHVgSPDxhwZklanPCXXzbzB2lw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.77.5.tgz", + "integrity": "sha512-/SW9ggXZJilbRbKvRHAxEuQM6Yr9piEpvK7/aDevFL2XFvBW9x+dTzpH5jPVEmM0qWdJisS1r5mEv8AXUUdQZg==", "cpu": [ "x64" ], @@ -2638,9 +2639,9 @@ } }, "node_modules/sass-embedded-linux-x64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.77.2.tgz", - "integrity": "sha512-czQOxGOX4U47jW9k+cbFBgSt/6FVx2WGLPqPvrgDiEToLJdZyvzUqrkpqQYfJ6hN1koqatCPEpDrUZBcTPGUGg==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.77.5.tgz", + "integrity": "sha512-3EmYeY+K8nMwIy1El9C+mPuONMQyXSCD6Yyztn3G7moPdZTqXrTL7kTJIl+SRq1tCcnOMMGXnBRE7Kpou1wd+w==", "cpu": [ "x64" ], @@ -2658,9 +2659,9 @@ } }, "node_modules/sass-embedded-win32-arm64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.77.2.tgz", - "integrity": "sha512-NA+4Y5PO04YQGtKNCyLrUjQU2nijskVA3Er/UYGtx66BBlWZ/ttbnlk+dU05SF5Jhjb3HtThGGH1meb7pKA+OQ==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.77.5.tgz", + "integrity": "sha512-dwVFOqkyfCRQgQB8CByH+MG93fp7IsfFaPDDCQVzVFAT00+HXk/dWFPMnv65XDDndGwsUE1KlZnjg8iOBDlRdw==", "cpu": [ "arm64" ], @@ -2678,9 +2679,9 @@ } }, "node_modules/sass-embedded-win32-ia32": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.77.2.tgz", - "integrity": "sha512-/3hGz4GefhVuuUu2gSOdsxBYym5Di0co0tZbtiokCU/8VhYhcAQ3v2Lni49VV6OnsyJLb1nUx+rbpd8cKO1U4w==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.77.5.tgz", + "integrity": "sha512-1ij/K5d2sHPJkytWiPJLoUOVHJOB6cSWXq7jmedeuGooWnBmqnWycmGkhBAEK/t6t1XgzMPsiJMGiHKh7fnBuA==", "cpu": [ "ia32" ], @@ -2698,9 +2699,9 @@ } }, "node_modules/sass-embedded-win32-x64": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.77.2.tgz", - "integrity": "sha512-joHLDICWmnR9Ca+LT9B+Fp85sCvV9F3gdtHtXLSuQAEulG5Ip1Z9euB3FUw+Z0s0Vz4MjNea+JD+TwO9eMrpyw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.77.5.tgz", + "integrity": "sha512-Pn6j0jDGeEAhuuVY0CaZaBa7yNkqimEsbUDYYuQ9xh+XdGvZ86SZf6HXHUVIyQUjHORLwQ5f0XoKYYzKfC0y9w==", "cpu": [ "x64" ], @@ -3037,15 +3038,15 @@ "peer": true }, "node_modules/vue": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz", - "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.29.tgz", + "integrity": "sha512-8QUYfRcYzNlYuzKPfge1UWC6nF9ym0lx7mpGVPJYNhddxEf3DD0+kU07NTL0sXuiT2HuJuKr/iEO8WvXvT0RSQ==", "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-sfc": "3.4.27", - "@vue/runtime-dom": "3.4.27", - "@vue/server-renderer": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-dom": "3.4.29", + "@vue/compiler-sfc": "3.4.29", + "@vue/runtime-dom": "3.4.29", + "@vue/server-renderer": "3.4.29", + "@vue/shared": "3.4.29" }, "peerDependencies": { "typescript": "*" @@ -3065,9 +3066,9 @@ } }, "node_modules/vue-router": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz", - "integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.3.tgz", + "integrity": "sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==", "dependencies": { "@vue/devtools-api": "^6.5.1" }, diff --git a/server/pop3/functions.go b/server/pop3/functions.go index 0bd62af4d..8fe7f9155 100644 --- a/server/pop3/functions.go +++ b/server/pop3/functions.go @@ -72,5 +72,5 @@ func getSafeArg(args []string, nr int) (string, error) { if nr < len(args) { return args[nr], nil } - return "", errors.New("Out of range") + return "", errors.New("-ERR out of range") } diff --git a/server/pop3/pop3.go b/server/pop3/pop3.go deleted file mode 100644 index 7c5fc0440..000000000 --- a/server/pop3/pop3.go +++ /dev/null @@ -1,324 +0,0 @@ -// Package pop3 is a simple POP3 server for Mailpit. -// By default it is disabled unless password credentials have been loaded. -// -// References: https://github.com/r0stig/golang-pop3 | https://github.com/inbucket/inbucket -// See RFC: https://datatracker.ietf.org/doc/html/rfc1939 -package pop3 - -import ( - "bufio" - "crypto/tls" - "fmt" - "net" - "strconv" - "strings" - "time" - - "github.com/axllent/mailpit/config" - "github.com/axllent/mailpit/internal/auth" - "github.com/axllent/mailpit/internal/logger" - "github.com/axllent/mailpit/internal/storage" - "github.com/axllent/mailpit/server/websockets" -) - -const ( - // UNAUTHORIZED state - UNAUTHORIZED = 1 - // TRANSACTION state - TRANSACTION = 2 - // UPDATE state - UPDATE = 3 -) - -// Run will start the pop3 server if enabled -func Run() { - if auth.POP3Credentials == nil || config.POP3Listen == "" { - // POP3 server is disabled without authentication - return - } - - var listener net.Listener - var err error - - if config.POP3TLSCert != "" { - cer, err2 := tls.LoadX509KeyPair(config.POP3TLSCert, config.POP3TLSKey) - if err2 != nil { - logger.Log().Errorf("[pop3] %s", err2.Error()) - return - } - - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cer}, - MinVersion: tls.VersionTLS12, - } - - listener, err = tls.Listen("tcp", config.POP3Listen, tlsConfig) - } else { - // unencrypted - listener, err = net.Listen("tcp", config.POP3Listen) - } - - if err != nil { - logger.Log().Errorf("[pop3] %s", err.Error()) - return - } - - logger.Log().Infof("[pop3] starting on %s", config.POP3Listen) - - for { - conn, err := listener.Accept() - if err != nil { - continue - } - - // run as goroutine - go handleClient(conn) - } -} - -type message struct { - ID string - Size float64 -} - -func handleClient(conn net.Conn) { - var ( - user = "" - state = 1 - toDelete = []string{} - ) - - defer func() { - if state == UPDATE { - for _, id := range toDelete { - _ = storage.DeleteMessages([]string{id}) - } - if len(toDelete) > 0 { - // update web UI to remove deleted messages - websockets.Broadcast("prune", nil) - } - } - - if err := conn.Close(); err != nil { - logger.Log().Errorf("[pop3] %s", err.Error()) - } - }() - - reader := bufio.NewReader(conn) - - messages := []message{} - - // State - // 1 = Unauthorized - // 2 = Transaction mode - // 3 = update mode - - logger.Log().Debugf("[pop3] connection opened by %s", conn.RemoteAddr().String()) - - // First welcome the new connection - sendResponse(conn, "+OK Mailpit POP3 server") - - timeoutDuration := 600 * time.Second - - for { - // POP3 server enforced a timeout of 30 seconds - if err := conn.SetDeadline(time.Now().Add(timeoutDuration)); err != nil { - logger.Log().Errorf("[pop3] %s", err.Error()) - return - } - - // Reads a line from the client - rawLine, err := reader.ReadString('\n') - if err != nil { - logger.Log().Errorf("[pop3] %s", err.Error()) - return - } - - // Parses the command - cmd, args := getCommand(rawLine) - - logger.Log().Debugf("[pop3] received: %s (%s)", strings.TrimSpace(rawLine), conn.RemoteAddr().String()) - - if cmd == "CAPA" { - // List our capabilities per RFC2449 - sendResponse(conn, "+OK Capability list follows") - sendResponse(conn, "TOP") - sendResponse(conn, "USER") - sendResponse(conn, "UIDL") - sendResponse(conn, "IMPLEMENTATION Mailpit") - sendResponse(conn, ".") - continue - } else if cmd == "USER" && state == UNAUTHORIZED { - if len(args) != 1 { - sendResponse(conn, "-ERR must supply a user") - return - } - // always true - stash for PASS - sendResponse(conn, "+OK") - user = args[0] - - } else if cmd == "PASS" && state == UNAUTHORIZED { - if len(args) != 1 { - sendResponse(conn, "-ERR must supply a password") - return - } - - pass := args[0] - if authUser(user, pass) { - sendResponse(conn, "+OK signed in") - messages, err = getMessages() - if err != nil { - logger.Log().Errorf("[pop3] %s", err.Error()) - } - state = 2 - } else { - sendResponse(conn, "-ERR invalid password") - logger.Log().Warnf("[pop3] failed login: %s", user) - } - - } else if cmd == "STAT" && state == TRANSACTION { - totalSize := float64(0) - for _, m := range messages { - totalSize = totalSize + m.Size - } - - sendResponse(conn, fmt.Sprintf("+OK %d %d", len(messages), int64(totalSize))) - - } else if cmd == "LIST" && state == TRANSACTION { - totalSize := float64(0) - for _, m := range messages { - totalSize = totalSize + m.Size - } - sendData(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), int64(totalSize))) - - // print all sizes - for row, m := range messages { - sendData(conn, fmt.Sprintf("%d %d", row+1, int64(m.Size))) // Convert Size to int64 when printing - } - // end - sendData(conn, ".") - - } else if cmd == "UIDL" && state == TRANSACTION { - totalSize := float64(0) - for _, m := range messages { - totalSize = totalSize + m.Size - } - - sendData(conn, "+OK unique-id listing follows") - - // print all message IDS - for row, m := range messages { - sendData(conn, fmt.Sprintf("%d %s", row+1, m.ID)) - } - // end - sendData(conn, ".") - - } else if cmd == "RETR" && state == TRANSACTION { - if len(args) != 1 { - sendResponse(conn, "-ERR no such message") - return - } - - nr, err := strconv.Atoi(args[0]) - if err != nil { - sendResponse(conn, "-ERR no such message") - return - } - - if nr < 1 || nr > len(messages) { - sendResponse(conn, "-ERR no such message") - return - } - - m := messages[nr-1] - raw, err := storage.GetMessageRaw(m.ID) - if err != nil { - sendResponse(conn, "-ERR no such message") - return - } - - size := len(raw) - sendData(conn, fmt.Sprintf("+OK %d octets", size)) - - // When all lines of the response have been sent, a - // final line is sent, consisting of a termination octet (decimal code - // 046, ".") and a CRLF pair. If any line of the multi-line response - // begins with the termination octet, the line is "byte-stuffed" by - // pre-pending the termination octet to that line of the response. - // @see: https://www.ietf.org/rfc/rfc1939.txt - sendData(conn, strings.Replace(string(raw), "\n.", "\n..", -1)) - sendData(conn, ".") - - } else if cmd == "TOP" && state == TRANSACTION { - arg, err := getSafeArg(args, 0) - if err != nil { - sendResponse(conn, "-ERR TOP requires two arguments") - return - } - nr, err := strconv.Atoi(arg) - if err != nil { - sendResponse(conn, "-ERR TOP requires two arguments") - return - } - - if nr < 1 || nr > len(messages) { - sendResponse(conn, "-ERR no such message") - return - } - arg2, err := getSafeArg(args, 1) - if err != nil { - sendResponse(conn, "-ERR TOP requires two arguments") - return - } - - lines, err := strconv.Atoi(arg2) - if err != nil { - sendResponse(conn, "-ERR TOP requires two arguments") - return - } - - m := messages[nr-1] - headers, body, err := getTop(m.ID, lines) - if err != nil { - sendResponse(conn, err.Error()) - return - } - - sendData(conn, "+OK Top of message follows") - sendData(conn, headers+"\r\n") - sendData(conn, body) - sendData(conn, ".") - - } else if cmd == "NOOP" && state == TRANSACTION { - sendData(conn, "+OK") - } else if cmd == "DELE" && state == TRANSACTION { - arg, _ := getSafeArg(args, 0) - nr, err := strconv.Atoi(arg) - if err != nil { - logger.Log().Warnf("[pop3] -ERR invalid DELETE integer: %s", arg) - sendResponse(conn, "-ERR invalid integer") - return - } - - if nr < 1 || nr > len(messages) { - logger.Log().Warnf("[pop3] -ERR no such message") - sendResponse(conn, "-ERR no such message") - return - } - toDelete = append(toDelete, messages[nr-1].ID) - - sendResponse(conn, "+OK") - - } else if cmd == "RSET" && state == TRANSACTION { - toDelete = []string{} - sendData(conn, "+OK") - - } else if cmd == "QUIT" { - state = UPDATE - return - } else { - logger.Log().Warnf("[pop3] -ERR %s not implemented", cmd) - sendResponse(conn, fmt.Sprintf("-ERR %s not implemented", cmd)) - } - } -} diff --git a/server/pop3/server.go b/server/pop3/server.go new file mode 100644 index 000000000..92a227c2d --- /dev/null +++ b/server/pop3/server.go @@ -0,0 +1,315 @@ +// Package pop3 is a simple POP3 server for Mailpit. +// By default it is disabled unless password credentials have been loaded. +// +// References: https://github.com/r0stig/golang-pop3 | https://github.com/inbucket/inbucket +// See RFC: https://datatracker.ietf.org/doc/html/rfc1939 +package pop3 + +import ( + "bufio" + "crypto/tls" + "fmt" + "io" + "net" + "strconv" + "strings" + "time" + + "github.com/axllent/mailpit/config" + "github.com/axllent/mailpit/internal/auth" + "github.com/axllent/mailpit/internal/logger" + "github.com/axllent/mailpit/internal/storage" + "github.com/axllent/mailpit/server/websockets" +) + +const ( + // AUTHORIZATION is the initial state + AUTHORIZATION = 1 + // TRANSACTION is the state after login + TRANSACTION = 2 + // UPDATE is the state before closing + UPDATE = 3 +) + +// Run will start the POP3 server if enabled +func Run() { + if auth.POP3Credentials == nil || config.POP3Listen == "" { + // POP3 server is disabled without authentication + return + } + + var listener net.Listener + var err error + + if config.POP3TLSCert != "" { + cer, err2 := tls.LoadX509KeyPair(config.POP3TLSCert, config.POP3TLSKey) + if err2 != nil { + logger.Log().Errorf("[pop3] %s", err2.Error()) + return + } + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cer}, + MinVersion: tls.VersionTLS12, + } + + listener, err = tls.Listen("tcp", config.POP3Listen, tlsConfig) + } else { + // unencrypted + listener, err = net.Listen("tcp", config.POP3Listen) + } + + if err != nil { + logger.Log().Errorf("[pop3] %s", err.Error()) + return + } + + logger.Log().Infof("[pop3] starting on %s", config.POP3Listen) + + for { + conn, err := listener.Accept() + if err != nil { + logger.Log().Errorf("[pop3] accept error: %s", err.Error()) + continue + } + + // run as goroutine + go handleClient(conn) + } +} + +type message struct { + ID string + Size float64 +} + +func handleClient(conn net.Conn) { + var ( + user = "" + state = AUTHORIZATION // Start with AUTHORIZATION state + toDelete []string // Track messages marked for deletion + messages []message + ) + + defer func() { + if state == UPDATE { + if len(toDelete) > 0 { + if err := storage.DeleteMessages(toDelete); err != nil { + logger.Log().Errorf("[pop3] error deleting: %s", err.Error()) + } + // Update web UI to remove deleted messages + websockets.Broadcast("prune", nil) + } + } + + if err := conn.Close(); err != nil { + logger.Log().Errorf("[pop3] %s", err.Error()) + } + }() + + reader := bufio.NewReader(conn) + + logger.Log().Debugf("[pop3] connection opened by %s", conn.RemoteAddr().String()) + + // First welcome the new connection + sendResponse(conn, "+OK Mailpit POP3 server") + + // Set 10 minutes timeout according to RFC1939 + timeoutDuration := 600 * time.Second + + for { + // Set read deadline + if err := conn.SetReadDeadline(time.Now().Add(timeoutDuration)); err != nil { + logger.Log().Errorf("[pop3] %s", err.Error()) + return + } + + // Reads a line from the client + rawLine, err := reader.ReadString('\n') + if err != nil { + if err == io.EOF { + logger.Log().Debugf("[pop3] client disconnected: %s", conn.RemoteAddr().String()) + } else { + logger.Log().Errorf("[pop3] read error: %s", err.Error()) + } + return + } + + // Parses the command + cmd, args := getCommand(rawLine) + cmd = strings.ToUpper(cmd) // Commands in the POP3 are case-insensitive + + logger.Log().Debugf("[pop3] received: %s (%s)", strings.TrimSpace(rawLine), conn.RemoteAddr().String()) + + switch cmd { + case "CAPA": + // List our capabilities per RFC2449 + sendResponse(conn, "+OK capability list follows") + sendResponse(conn, "TOP") + sendResponse(conn, "USER") + sendResponse(conn, "UIDL") + sendResponse(conn, "IMPLEMENTATION Mailpit") + sendResponse(conn, ".") + case "USER": + if state == AUTHORIZATION { + if len(args) != 1 { + sendResponse(conn, "-ERR must supply a user") + return + } + sendResponse(conn, "+OK") + user = args[0] + } else { + sendResponse(conn, "-ERR user already specified") + } + case "PASS": + if state == AUTHORIZATION { + if user == "" { + sendResponse(conn, "-ERR must supply a user") + return + } + if len(args) != 1 { + sendResponse(conn, "-ERR must supply a password") + return + } + + pass := args[0] + if authUser(user, pass) { + sendResponse(conn, "+OK signed in") + var err error + messages, err = getMessages() + if err != nil { + logger.Log().Errorf("[pop3] %s", err.Error()) + } + state = TRANSACTION + } else { + sendResponse(conn, "-ERR invalid password") + logger.Log().Warnf("[pop3] failed login: %s", user) + } + } else { + sendResponse(conn, "-ERR user not specified") + } + case "STAT", "LIST", "UIDL", "RETR", "TOP", "NOOP", "DELE", "RSET": + if state == TRANSACTION { + handleTransactionCommand(conn, cmd, args, messages, &toDelete) + } else { + sendResponse(conn, "-ERR user not authenticated") + } + case "QUIT": + sendResponse(conn, "+OK goodbye") + state = UPDATE + return + default: + sendResponse(conn, "-ERR unknown command") + } + } +} + +func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages []message, toDelete *[]string) { + switch cmd { + case "STAT": + totalSize := float64(0) + for _, m := range messages { + totalSize += m.Size + } + sendResponse(conn, fmt.Sprintf("+OK %d %d", len(messages), int64(totalSize))) + case "LIST": + totalSize := float64(0) + for _, m := range messages { + totalSize += m.Size + } + sendResponse(conn, fmt.Sprintf("+OK %d messages (%d octets)", len(messages), int64(totalSize))) + + for row, m := range messages { + sendResponse(conn, fmt.Sprintf("%d %d", row+1, int64(m.Size))) // Convert Size to int64 when printing + } + sendResponse(conn, ".") + case "UIDL": + sendResponse(conn, "+OK unique-id listing follows") + for row, m := range messages { + sendResponse(conn, fmt.Sprintf("%d %s", row+1, m.ID)) + } + sendResponse(conn, ".") + case "RETR": + if len(args) != 1 { + sendResponse(conn, "-ERR no such message") + return + } + + nr, err := strconv.Atoi(args[0]) + if err != nil || nr < 1 || nr > len(messages) { + sendResponse(conn, "-ERR no such message") + return + } + + m := messages[nr-1] + raw, err := storage.GetMessageRaw(m.ID) + if err != nil { + sendResponse(conn, "-ERR no such message") + return + } + size := len(raw) + sendResponse(conn, fmt.Sprintf("+OK %d octets", size)) + + // When all lines of the response have been sent, a + // final line is sent, consisting of a termination octet (decimal code + // 046, ".") and a CRLF pair. If any line of the multi-line response + // begins with the termination octet, the line is "byte-stuffed" by + // pre-pending the termination octet to that line of the response. + // @see: https://www.ietf.org/rfc/rfc1939.txt + sendData(conn, strings.Replace(string(raw), "\n.", "\n..", -1)) + sendResponse(conn, ".") + case "TOP": + arg, err := getSafeArg(args, 0) + if err != nil { + sendResponse(conn, "-ERR TOP requires two arguments") + return + } + nr, err := strconv.Atoi(arg) + if err != nil || nr < 1 || nr > len(messages) { + sendResponse(conn, "-ERR no such message") + return + } + + arg2, err := getSafeArg(args, 1) + if err != nil { + sendResponse(conn, "-ERR TOP requires two arguments") + return + } + + lines, err := strconv.Atoi(arg2) + if err != nil { + sendResponse(conn, "-ERR TOP requires two arguments") + return + } + + m := messages[nr-1] + headers, body, err := getTop(m.ID, lines) + if err != nil { + sendResponse(conn, err.Error()) + return + } + + sendResponse(conn, "+OK top of message follows") + sendData(conn, headers+"\r\n") + sendData(conn, body) + sendResponse(conn, ".") + case "NOOP": + sendResponse(conn, "+OK") + case "DELE": + arg, _ := getSafeArg(args, 0) + nr, err := strconv.Atoi(arg) + if err != nil || nr < 1 || nr > len(messages) { + sendResponse(conn, "-ERR no such message") + return + } + + m := messages[nr-1] + *toDelete = append(*toDelete, m.ID) + sendResponse(conn, "+OK message marked for deletion") + case "RSET": + *toDelete = []string{} + sendResponse(conn, "+OK") + default: + sendResponse(conn, "-ERR unknown command") + } +}