diff --git a/assets/icons/tray/sync@2x.png b/assets/icons/tray/sync@2x.png new file mode 100644 index 0000000..e138a31 Binary files /dev/null and b/assets/icons/tray/sync@2x.png differ diff --git a/assets/icons/tray/warning@2x.png b/assets/icons/tray/warning@2x.png new file mode 100644 index 0000000..ff1d129 Binary files /dev/null and b/assets/icons/tray/warning@2x.png differ diff --git a/package-lock.json b/package-lock.json index 6cc0cce..69d9f5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,20 @@ { "name": "@filen/desktop", - "version": "3.0.34", + "version": "3.0.35", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@filen/desktop", - "version": "3.0.34", + "version": "3.0.35", "license": "AGPLv3", "dependencies": { - "@filen/network-drive": "^0.9.35", - "@filen/s3": "^0.2.45", - "@filen/sdk": "^0.1.183", + "@filen/network-drive": "^0.9.36", + "@filen/s3": "^0.2.46", + "@filen/sdk": "^0.1.187", "@filen/sync": "^0.1.84", - "@filen/web": "^0.1.67", - "@filen/webdav": "^0.2.60", + "@filen/web": "^0.1.71", + "@filen/webdav": "^0.2.61", "axios": "^0.28.1", "cors": "^2.8.5", "electron-updater": "^6.4.0-alpha.1", @@ -81,6 +81,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -93,6 +94,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -105,6 +107,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -113,6 +116,7 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", + "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.6", @@ -142,6 +146,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, "dependencies": { "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -156,6 +161,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -169,6 +175,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, "dependencies": { "@babel/compat-data": "^7.24.7", "@babel/helper-validator-option": "^7.24.7", @@ -184,6 +191,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -195,6 +203,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -208,6 +217,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -220,6 +230,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -233,6 +244,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -244,6 +256,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -257,6 +270,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -269,6 +283,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -282,6 +297,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", @@ -309,6 +325,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -321,6 +338,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -334,6 +352,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -345,6 +364,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -358,6 +378,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -366,6 +387,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -374,6 +396,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -382,6 +405,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -394,6 +418,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -407,6 +432,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -421,6 +447,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -620,6 +647,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -633,6 +661,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -646,6 +675,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.7", @@ -666,6 +696,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", @@ -679,6 +710,7 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.6", "@babel/helper-validator-identifier": "^7.24.6", @@ -2203,13 +2235,13 @@ } }, "node_modules/@filen/network-drive": { - "version": "0.9.35", - "resolved": "https://registry.npmjs.org/@filen/network-drive/-/network-drive-0.9.35.tgz", - "integrity": "sha512-44J9CT3aQbfGW2N2/FaOhLx+EOSEARmZcxCnmPwDS3rIX9Q+EgX+lbd/8Fg/6NxO7EYx4ei2q2j0G1ToSWBfHg==", + "version": "0.9.36", + "resolved": "https://registry.npmjs.org/@filen/network-drive/-/network-drive-0.9.36.tgz", + "integrity": "sha512-xBqPXs76wvjxTa+B1AkiuoXiKs/VdO/yEWW0hA/KIeYSFEYU8nB90U5f7/FA2Btf9qV94caRONlskhFZIcUgQg==", "license": "AGPLv3", "dependencies": { - "@filen/sdk": "^0.1.181", - "@filen/webdav": "^0.2.60", + "@filen/sdk": "^0.1.183", + "@filen/webdav": "^0.2.61", "@vscode/sudo-prompt": "^9.3.1", "axios": "^1.7.6", "diskusage-ng": "^1.0.4", @@ -2274,12 +2306,12 @@ } }, "node_modules/@filen/s3": { - "version": "0.2.45", - "resolved": "https://registry.npmjs.org/@filen/s3/-/s3-0.2.45.tgz", - "integrity": "sha512-IQ6NKMO56OeFDoAdL1PP8eFjl9v2QqZpYT5/oOv6gGgMPcFU1/OE4BvBJmshqYPv1faH0hEYiMW6imPD5Ci6zQ==", + "version": "0.2.46", + "resolved": "https://registry.npmjs.org/@filen/s3/-/s3-0.2.46.tgz", + "integrity": "sha512-+cSbNK1XyC1O9e1mjZHk4G+Em6/9HD3UJRJnRVakKQxOdtpQV+Tt7JjYYAQjBJQNZmUC3YuibnPJ4rqfmOdHMg==", "license": "AGPLv3", "dependencies": { - "@filen/sdk": "^0.1.181", + "@filen/sdk": "^0.1.183", "aws-sdk": "^2.1692.0", "aws4-express": "^0.10.1", "body-parser": "^1.20.2", @@ -2339,9 +2371,9 @@ } }, "node_modules/@filen/sdk": { - "version": "0.1.183", - "resolved": "https://registry.npmjs.org/@filen/sdk/-/sdk-0.1.183.tgz", - "integrity": "sha512-AANBuzKN4SatYwjQkAjN382itVWNHpB65qLFNa5nlt9WCMYqc9xBvjueZYnJDGtz6sMLAD/fpokFB3JxGk/pSw==", + "version": "0.1.187", + "resolved": "https://registry.npmjs.org/@filen/sdk/-/sdk-0.1.187.tgz", + "integrity": "sha512-IxhkMiUXCetdfIShTWKVT9RNL6pAptav3To6f8du8Su0TzKnQZWfQVu3OzNHiTmXZrGeQwqtUJd8VNeCKPJYXA==", "license": "AGPLv3", "dependencies": { "agentkeepalive": "^4.5.0", @@ -2414,17 +2446,17 @@ } }, "node_modules/@filen/web": { - "version": "0.1.67", - "resolved": "https://registry.npmjs.org/@filen/web/-/web-0.1.67.tgz", - "integrity": "sha512-ELWXkwlqwSAz2C4tq6JKpEV3tej2f18SZJrFMhOSSgYGrhoBRIwIJI1f3UdfrVAcXIin0LftTFF69tLZS0cF6w==", + "version": "0.1.71", + "resolved": "https://registry.npmjs.org/@filen/web/-/web-0.1.71.tgz", + "integrity": "sha512-n+2VXV1YaCFKsAhnmyw0AyOOoDHOepZrsTk8/kMmqd0mZeLCmDwnI97jJPSwrAjMM3zNBxCr6RLZIYI/JWP8mQ==", "dependencies": { "@alptugidin/react-circular-progress-bar": "^1.1.2", "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", "@filen/desktop": "^3.0.34", - "@filen/network-drive": "^0.9.34", - "@filen/sdk": "^0.1.181", - "@filen/sync": "^0.1.81", + "@filen/network-drive": "^0.9.36", + "@filen/sdk": "^0.1.187", + "@filen/sync": "^0.1.84", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", @@ -2474,7 +2506,6 @@ "localforage-memoryStorageDriver": "^0.9.2", "lodash": "^4.17.21", "lucide-react": "^0.344.0", - "million": "^3.1.11", "mime-types": "^2.1.35", "native-file-system-adapter": "github:jimmywarting/native-file-system-adapter", "pdfjs-dist": "^4.0.379", @@ -2507,12 +2538,12 @@ } }, "node_modules/@filen/webdav": { - "version": "0.2.60", - "resolved": "https://registry.npmjs.org/@filen/webdav/-/webdav-0.2.60.tgz", - "integrity": "sha512-UxEY23CH79RANxHat4SMdcMjoe8LzssQ8cJpBuQTvIqI4OQcbZwDSCpmHCRUk6A3+GUky/IrTwRXVTWL+4GCTw==", + "version": "0.2.61", + "resolved": "https://registry.npmjs.org/@filen/webdav/-/webdav-0.2.61.tgz", + "integrity": "sha512-5glLYzCLBT9w3veybK6AhMHQLgq+VOFcWhxGhegq1BmeJQvzOeNjdPOkGj3d8ncjS3qsO6ItUDTIgnuBd5noIQ==", "license": "AGPLv3", "dependencies": { - "@filen/sdk": "^0.1.181", + "@filen/sdk": "^0.1.183", "body-parser": "^1.20.2", "express": "^4.19.2", "express-rate-limit": "^7.4.0", @@ -3544,6 +3575,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3557,6 +3589,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -3565,6 +3598,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -3572,12 +3606,14 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -5280,27 +5316,6 @@ "@lezer/lr": "^1.0.0" } }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -6568,6 +6583,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -6688,6 +6704,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -6699,6 +6716,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -7296,17 +7314,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -7463,6 +7470,7 @@ "version": "4.23.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -7937,6 +7945,7 @@ "version": "1.0.30001653", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz", "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -7981,6 +7990,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -8043,40 +8053,6 @@ "node": "*" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -8273,6 +8249,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -8280,7 +8257,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/color-support": { "version": "1.1.3", @@ -8499,7 +8477,8 @@ "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "node_modules/cookie": { "version": "0.7.1", @@ -9538,7 +9517,8 @@ "node_modules/electron-to-chromium": { "version": "1.4.807", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.807.tgz", - "integrity": "sha512-kSmJl2ZwhNf/bcIuCH/imtNOKlpkLDn2jqT5FJ+/0CXjhnFaOa9cOe9gHKKy71eM49izwuQjZhKk+lWQ1JxB7A==" + "integrity": "sha512-kSmJl2ZwhNf/bcIuCH/imtNOKlpkLDn2jqT5FJ+/0CXjhnFaOa9cOe9gHKKy71eM49izwuQjZhKk+lWQ1JxB7A==", + "dev": true }, "node_modules/electron-updater": { "version": "6.4.0-alpha.1", @@ -9816,6 +9796,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, "engines": { "node": ">=6" } @@ -9829,6 +9810,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -10119,11 +10101,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -10757,6 +10734,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -10807,6 +10785,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -10999,6 +10978,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, "engines": { "node": ">=4" } @@ -11121,6 +11101,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -11996,17 +11977,6 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -14241,6 +14211,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -14283,6 +14254,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -14577,6 +14549,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -15623,33 +15596,6 @@ "node": ">=8.6" } }, - "node_modules/million": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/million/-/million-3.1.11.tgz", - "integrity": "sha512-6Vh1s0da0PzSqbbp9Zd8yMTIkOWnvBU4vNJCMHTZPXaY3fZ5h+N7s5croS/RBgjJIHz3WQZnvyNBQz7gQ6cqJg==", - "dependencies": { - "@babel/core": "^7.23.7", - "@babel/types": "^7.23.6", - "@rollup/pluginutils": "^5.1.0", - "kleur": "^4.1.5", - "undici": "^6.3.0", - "unplugin": "^1.6.0" - }, - "bin": { - "million": "cli.js" - }, - "funding": { - "url": "https://github.com/sponsors/aidenybai" - } - }, - "node_modules/million/node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -16123,7 +16069,8 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/node-watch": { "version": "0.7.4", @@ -16695,6 +16642,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -17395,17 +17343,6 @@ "node": ">=10" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -18023,6 +17960,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -18839,6 +18777,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -19055,6 +18994,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, "engines": { "node": ">=4" } @@ -19280,14 +19220,6 @@ "node": "*" } }, - "node_modules/undici": { - "version": "6.19.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", - "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", - "engines": { - "node": ">=18.17" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -19439,24 +19371,11 @@ "node": ">= 0.8" } }, - "node_modules/unplugin": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.1.tgz", - "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==", - "dependencies": { - "acorn": "^8.11.3", - "chokidar": "^3.6.0", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.6.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -19801,19 +19720,6 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-virtual-modules": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==" - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -20083,7 +19989,8 @@ "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "2.6.0", diff --git a/package.json b/package.json index 327e9c4..214feaf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@filen/desktop", - "version": "3.0.34", - "buildNumber": 334, + "version": "3.0.35", + "buildNumber": 335, "description": "Filen Desktop Client", "author": "Filen Cloud Dienste UG (haftungsbeschränkt) ", "main": "dist/index.js", @@ -65,12 +65,12 @@ "yaml": "^2.6.0" }, "dependencies": { - "@filen/network-drive": "^0.9.35", - "@filen/s3": "^0.2.45", - "@filen/sdk": "^0.1.183", + "@filen/network-drive": "^0.9.36", + "@filen/s3": "^0.2.46", + "@filen/sdk": "^0.1.187", "@filen/sync": "^0.1.84", - "@filen/web": "^0.1.67", - "@filen/webdav": "^0.2.60", + "@filen/web": "^0.1.71", + "@filen/webdav": "^0.2.61", "axios": "^0.28.1", "cors": "^2.8.5", "electron-updater": "^6.4.0-alpha.1", diff --git a/src/assets/index.ts b/src/assets/index.ts index 197426f..25c9ce7 100644 --- a/src/assets/index.ts +++ b/src/assets/index.ts @@ -1,52 +1,64 @@ -import { nativeImage } from "electron" +import { nativeImage, type NativeImage } from "electron" import pathModule from "path" -import memoize from "lodash/memoize" - -export const getAppIcon = memoize(() => { - return nativeImage.createFromPath( - pathModule.join( - __dirname, - "..", - "..", - "assets", - "icons", - "app", - `${process.platform}.${process.platform === "win32" ? "ico" : process.platform === "darwin" ? "icns" : "png"}` - ) +import { type TrayState } from "../types" + +export const OVERLAY_ICON = nativeImage.createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "app", "overlay", "0.png")) + +export const APP_ICON = nativeImage.createFromPath( + pathModule.join( + __dirname, + "..", + "..", + "assets", + "icons", + "app", + `${process.platform}.${process.platform === "win32" ? "ico" : process.platform === "darwin" ? "icns" : "png"}` ) -}) - -export const getTrayIcon = memoize((notification: boolean) => { - /*return nativeImage.createFromPath( - pathModule.join( - __dirname, - "..", - "..", - "assets", - "icons", - "tray", - nativeTheme.shouldUseDarkColors ? "light" : "dark", - `${process.platform}${notification ? "Notification" : ""}${process.platform === "darwin" ? "Template" : ""}.${ - process.platform === "win32" ? "ico" : process.platform === "darwin" ? "png" : "png" - }` - ) - )*/ - - return nativeImage - .createFromPath( - pathModule.join(__dirname, "..", "..", "assets", "icons", "tray", `${notification ? "notification@2x.png" : "normal@2x.png"}`) - ) - .resize({ - width: 16, - height: 16 - }) -}) +) -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export const getOverlayIcon = memoize((notificationCount: number) => { - //const count = notificationCount > 9 ? 99 : notificationCount +export const TRAY_ICON_NORMAL = nativeImage + .createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "tray", "normal@2x.png")) + .resize({ + width: 16, + height: 16 + }) + +export const TRAY_ICON_SYNC = nativeImage + .createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "tray", "sync@2x.png")) + .resize({ + width: 16, + height: 16 + }) - const count = 0 +export const TRAY_ICON_NOTIFICATION = nativeImage + .createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "tray", "notification@2x.png")) + .resize({ + width: 16, + height: 16 + }) - return nativeImage.createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "app", "overlay", `${count}.png`)) -}) +export const TRAY_ICON_WARNING = nativeImage + .createFromPath(pathModule.join(__dirname, "..", "..", "assets", "icons", "tray", "warning@2x.png")) + .resize({ + width: 16, + height: 16 + }) + +export function getAppIcon(): NativeImage { + return APP_ICON +} + +export function getTrayIcon({ notificationCount, isSyncing, warningCount, errorCount }: TrayState): NativeImage { + return notificationCount + errorCount > 0 + ? TRAY_ICON_NOTIFICATION + : warningCount > 0 + ? TRAY_ICON_WARNING + : isSyncing + ? TRAY_ICON_SYNC + : TRAY_ICON_NORMAL +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function getOverlayIcon(notificationCount: number): NativeImage { + return OVERLAY_ICON +} diff --git a/src/index.ts b/src/index.ts index fcd5082..94ecff6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, shell, Tray, nativeTheme, dialog, Menu } from "electron" +import { app, BrowserWindow, shell, dialog } from "electron" import pathModule from "path" import IPC from "./ipc" import FilenSDK from "@filen/sdk" @@ -7,12 +7,14 @@ import Cloud from "./lib/cloud" import FS from "./lib/fs" import { IS_ELECTRON } from "./constants" import Worker from "./worker" -import { getAppIcon, getTrayIcon, getOverlayIcon } from "./assets" +import { getAppIcon } from "./assets" import Updater from "./lib/updater" import isDev from "./isDev" import Logger from "./lib/logger" import serveProd from "./lib/serve" import WindowState from "./lib/windowState" +import Status from "./lib/status" +import Options from "./lib/options" if (IS_ELECTRON) { // Needs to be here, otherwise Chromium's FileSystemAccess API won't work. Waiting for the electron team to fix it. @@ -40,13 +42,14 @@ export class FilenDesktop { cloud: Cloud fs: FS } - public notificationCount = 0 - public tray: Tray | null = null public updater: Updater public logger: Logger public isUnityRunning: boolean = process.platform === "linux" ? app.isUnityRunning() : false public serve: (window: BrowserWindow) => Promise public windowState: WindowState + public minimizeToTray: boolean = false + public status: Status + public options: Options /** * Creates an instance of FilenDesktop. @@ -67,6 +70,8 @@ export class FilenDesktop { this.worker = new Worker(this) this.updater = new Updater(this) this.logger = new Logger(false, false) + this.status = new Status(this) + this.options = new Options() } /** @@ -103,7 +108,14 @@ export class FilenDesktop { return } + const options = await this.options.get() + await app.whenReady() + + if (options.startMinimized && process.platform === "darwin") { + app?.dock?.hide() + } + await this.createLauncherWindow() this.initializeSDK() @@ -202,7 +214,9 @@ export class FilenDesktop { await this.launcherWindow.loadFile(pathModule.join("..", "public", "launcher.html")) - if (!app.commandLine.hasSwitch("hidden") && !process.argv.includes("--hidden")) { + const startMinimized = (await this.options.get()).startMinimized ?? false + + if (!app.commandLine.hasSwitch("hidden") && !process.argv.includes("--hidden") && !startMinimized) { this.launcherWindow.show() } } @@ -216,7 +230,7 @@ export class FilenDesktop { this.launcherWindow = null } - private showOrOpenDriveWindow(): void { + public showOrOpenDriveWindow(): void { if (BrowserWindow.getAllWindows().length === 0) { this.createMainWindow().catch(err => { this.logger.log("error", err) @@ -225,7 +239,11 @@ export class FilenDesktop { return } - this.driveWindow?.show() + if (this.driveWindow?.isMinimized()) { + this.driveWindow?.restore() + } else { + this.driveWindow?.show() + } } private async createMainWindow(): Promise { @@ -233,7 +251,7 @@ export class FilenDesktop { return } - const state = await this.windowState.get() + const [state, options] = await Promise.all([this.windowState.get(), this.options.get()]) this.driveWindow = new BrowserWindow({ width: state ? state.width : 1280, @@ -263,6 +281,8 @@ export class FilenDesktop { } }) + this.status.initialize() + if (state) { this.driveWindow.setBounds({ width: state.width, @@ -274,82 +294,36 @@ export class FilenDesktop { this.windowState.manage(this.driveWindow) - if (!this.tray) { - this.tray = new Tray(getTrayIcon(this.notificationCount > 0)) - - this.tray.setContextMenu(null) - this.tray.setToolTip("Filen") - - this.tray.on("click", () => { - if (process.platform !== "win32") { - return - } - - this.showOrOpenDriveWindow() - }) - - this.tray.setContextMenu( - Menu.buildFromTemplate([ - { - label: "Filen", - type: "normal", - icon: getTrayIcon(false), - enabled: false - }, - { - label: "Open", - type: "normal", - click: () => { - this.showOrOpenDriveWindow() - } - }, - { - label: "Separator", - type: "separator" - }, - { - label: "Exit", - type: "normal", - click: () => { - app?.quit() - } - } - ]) - ) - } - if (process.platform === "win32") { this.driveWindow?.setThumbarButtons([]) } - this.driveWindow.on("closed", () => { + this.driveWindow?.on("closed", () => { this.driveWindow = null }) - // Handle different icons based on the user's theme (dark/light) - nativeTheme.on("updated", () => { - this.driveWindow?.setIcon(getAppIcon()) - this.tray?.setImage(getTrayIcon(this.notificationCount > 0)) - - if (process.platform === "win32") { - if (this.notificationCount > 0) { - this.driveWindow?.setOverlayIcon(getOverlayIcon(this.notificationCount), this.notificationCount.toString()) - } else { - this.driveWindow?.setOverlayIcon(null, "") - } + this.driveWindow?.on("minimize", () => { + if (process.platform === "darwin" && this.minimizeToTray) { + app?.dock?.hide() } + }) - if (process.platform === "darwin") { - app?.dock?.setIcon(getAppIcon()) + this.driveWindow?.on("show", () => { + if (process.platform === "darwin" && !app?.dock?.isVisible()) { + app?.dock?.show() } + }) + + this.driveWindow?.on("close", e => { + if ((process.platform === "darwin" || this.minimizeToTray) && !this.driveWindow?.isMinimized()) { + e.preventDefault() - if (process.platform === "darwin" || (process.platform === "linux" && this.isUnityRunning)) { - app?.setBadgeCount(this.notificationCount) + this.driveWindow?.minimize() } }) // Open links in default external browser - this.driveWindow.webContents.setWindowOpenHandler(({ url }) => { + this.driveWindow?.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url) return { @@ -358,13 +332,13 @@ export class FilenDesktop { }) if (isDev) { - await this.driveWindow.loadURL("http://localhost:5173") + await this.driveWindow?.loadURL("http://localhost:5173") } else { await this.serve(this.driveWindow) } - if (!app.commandLine.hasSwitch("hidden") && !process.argv.includes("--hidden")) { - this.driveWindow.show() + if (!app.commandLine.hasSwitch("hidden") && !process.argv.includes("--hidden") && !options.startMinimized) { + this.driveWindow?.show() } } } diff --git a/src/ipc/index.ts b/src/ipc/index.ts index 6ee8ad4..534ebe7 100644 --- a/src/ipc/index.ts +++ b/src/ipc/index.ts @@ -9,7 +9,6 @@ import fs from "fs-extra" import { v4 as uuidv4 } from "uuid" import { isPortInUse, canStartServerOnIPAndPort, type SerializedError, getDiskType, getLocalDirectorySize } from "../utils" import { type SyncMessage } from "@filen/sync/dist/types" -import { getTrayIcon, getAppIcon, getOverlayIcon } from "../assets" import { type ProgressInfo, type UpdateDownloadedEvent } from "electron-updater" import { DISALLOWED_SYNC_DIRS } from "../constants" import os from "os" @@ -333,32 +332,38 @@ export class IPC { }) ipcMain.handle("updateNotificationCount", async (_, count: number) => { - this.desktop.notificationCount = count + this.desktop.status.trayState.notificationCount = count - this.desktop.driveWindow?.setIcon(getAppIcon()) - this.desktop.tray?.setImage(getTrayIcon(count > 0)) + this.desktop.status.update() + }) - if (process.platform === "win32") { - if (count > 0) { - this.desktop.driveWindow?.setOverlayIcon(getOverlayIcon(count), count.toString()) - } else { - this.desktop.driveWindow?.setOverlayIcon(null, "") - } - } + ipcMain.handle("updateErrorCount", async (_, count: number) => { + this.desktop.status.trayState.errorCount = count - if (process.platform === "darwin") { - app.dock.setIcon(getAppIcon()) - } + this.desktop.status.update() + }) - if (process.platform === "darwin" || (process.platform === "linux" && this.desktop.isUnityRunning)) { - app.setBadgeCount(count) - } + ipcMain.handle("updateWarningCount", async (_, count: number) => { + this.desktop.status.trayState.warningCount = count + + this.desktop.status.update() + }) + + ipcMain.handle("updateIsSyncing", async (_, isSyncing: boolean) => { + this.desktop.status.trayState.isSyncing = isSyncing + + this.desktop.status.update() }) ipcMain.handle("toggleAutoLaunch", async (_, enabled: boolean) => { app.setLoginItemSettings({ openAtLogin: enabled, - ...(enabled ? { openAsHidden: true, args: ["--hidden"] } : {}) + ...(enabled + ? { + openAsHidden: true, + args: ["--hidden"] + } + : {}) }) }) @@ -432,6 +437,20 @@ export class IPC { ipcMain.handle("isPathSyncedByICloud", async (_, path: string) => { return await isPathSyncedByICloud(path) }) + + ipcMain.handle("setMinimizeToTray", async (_, minimizeToTray: boolean) => { + this.desktop.minimizeToTray = minimizeToTray + + await this.desktop.options.update({ + minimizeToTray + }) + }) + + ipcMain.handle("setStartMinimized", async (_, startMinimized: boolean) => { + await this.desktop.options.update({ + startMinimized + }) + }) } /** @@ -675,7 +694,11 @@ export class IPC { }) ipcMain.handle("showWindow", async (): Promise => { - this.desktop.driveWindow?.show() + if (this.desktop.driveWindow?.isMinimized()) { + this.desktop.driveWindow?.restore() + } else { + this.desktop.driveWindow?.show() + } }) ipcMain.handle("hideWindow", async (): Promise => { diff --git a/src/lib/options.ts b/src/lib/options.ts new file mode 100644 index 0000000..c23f74a --- /dev/null +++ b/src/lib/options.ts @@ -0,0 +1,88 @@ +import writeFileAtomic from "write-file-atomic" +import fs from "fs-extra" +import { app } from "electron" +import pathModule from "path" + +export const OPTIONS_VERSION = 1 + +export type OptionsType = { + minimizeToTray?: boolean + startMinimized?: boolean +} + +export class Options { + private path: string | null = null + private cache: OptionsType | null = null + + private getPath(): string { + if (!this.path) { + this.path = pathModule.join(app.getPath("userData"), `options.v${OPTIONS_VERSION}.json`) + } + + return this.path + } + + public async reset(): Promise { + try { + const path = this.getPath() + + await fs.rm(path, { + force: true, + maxRetries: 60 * 10, + recursive: true, + retryDelay: 100 + }) + + this.cache = {} + } catch (e) { + console.error(e) + } + } + + public async get(): Promise { + if (this.cache) { + return this.cache + } + + try { + const path = this.getPath() + + if (!(await fs.exists(path))) { + return {} + } + + const options: OptionsType = JSON.parse(await fs.readFile(path, "utf-8")) + + this.cache = options + + return options + } catch (e) { + console.error(e) + + return {} + } + } + + public async save(options: OptionsType): Promise { + try { + const path = this.getPath() + + await writeFileAtomic(path, JSON.stringify(options)) + + this.cache = options + } catch (e) { + console.error(e) + } + } + + public async update(options: Partial): Promise { + const current = await this.get() + + await this.save({ + ...current, + ...options + }) + } +} + +export default Options diff --git a/src/lib/status.ts b/src/lib/status.ts new file mode 100644 index 0000000..6212c3b --- /dev/null +++ b/src/lib/status.ts @@ -0,0 +1,96 @@ +import type FilenDesktop from ".." +import { Tray, app, Menu, nativeTheme } from "electron" +import { getTrayIcon, getAppIcon, getOverlayIcon } from "../assets" +import { type TrayState } from "../types" + +export class Status { + private readonly desktop: FilenDesktop + public tray: Tray | null = null + public trayState: TrayState = { + notificationCount: 0, + isSyncing: false, + errorCount: 0, + warningCount: 0 + } + + public constructor(desktop: FilenDesktop) { + this.desktop = desktop + } + + public initialize(): void { + if (!this.tray) { + this.tray = new Tray(getTrayIcon(this.trayState)) + + this.tray.setContextMenu(null) + this.tray.setToolTip("Filen") + + this.tray.on("click", () => { + if (process.platform !== "win32") { + return + } + + this.desktop.showOrOpenDriveWindow() + }) + + this.tray.setContextMenu( + Menu.buildFromTemplate([ + { + label: "Filen", + type: "normal", + icon: getTrayIcon(this.trayState), + enabled: false + }, + { + label: "Open", + type: "normal", + click: () => { + this.desktop.showOrOpenDriveWindow() + } + }, + { + label: "Separator", + type: "separator" + }, + { + label: "Exit", + type: "normal", + click: () => { + app?.quit() + } + } + ]) + ) + } + + // Handle different icons based on the user's theme (dark/light) + nativeTheme.on("updated", () => { + this.update() + }) + } + + public update(): void { + this.desktop.driveWindow?.setIcon(getAppIcon()) + this.tray?.setImage(getTrayIcon(this.trayState)) + + if (process.platform === "win32") { + if (this.trayState.notificationCount > 0) { + this.desktop.driveWindow?.setOverlayIcon( + getOverlayIcon(this.trayState.notificationCount), + this.trayState.notificationCount.toString() + ) + } else { + this.desktop.driveWindow?.setOverlayIcon(null, "") + } + } + + if (process.platform === "darwin") { + app?.dock?.setIcon(getAppIcon()) + } + + if (process.platform === "darwin" || (process.platform === "linux" && this.desktop.isUnityRunning)) { + app?.setBadgeCount(this.trayState.notificationCount) + } + } +} + +export default Status diff --git a/src/lib/updater.ts b/src/lib/updater.ts index 2bf25a2..062651d 100644 --- a/src/lib/updater.ts +++ b/src/lib/updater.ts @@ -140,6 +140,11 @@ export class Updater { app.removeAllListeners("window-all-closed") app.removeAllListeners("will-quit") + this.desktop.driveWindow?.removeAllListeners("close") + this.desktop.driveWindow?.removeAllListeners("show") + this.desktop.driveWindow?.removeAllListeners("minimize") + this.desktop.driveWindow?.removeAllListeners("maximize") + await this.desktop.worker.stop().catch(err => { this.desktop.logger.log("error", err, "updater.installUpdate") this.desktop.logger.log("error", err) diff --git a/src/preload.ts b/src/preload.ts index 3f52f37..52c78e8 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -94,6 +94,9 @@ export type DesktopAPI = { syncUpdateIgnorerContent: (params: { uuid: string; content: string }) => Promise syncToggleLocalTrash: (params: { uuid: string; enabled: boolean }) => Promise updateNotificationCount: (count: number) => Promise + updateErrorCount: (count: number) => Promise + updateWarningCount: (count: number) => Promise + updateIsSyncing: (isSyncing: boolean) => Promise toggleAutoLaunch: (enabled: boolean) => Promise installUpdate: () => Promise isWinFSPInstalled: () => Promise @@ -114,6 +117,8 @@ export type DesktopAPI = { isFUSETInstalledOnMacOS: () => Promise tryingToSyncDesktop: (path: string) => Promise isPathSyncedByICloud: (path: string) => Promise + setMinimizeToTray: (minimizeToTray: boolean) => Promise + setStartMinimized: (startMinimized: boolean) => Promise } if (env.isBrowser || env.isElectron) { @@ -194,6 +199,9 @@ if (env.isBrowser || env.isElectron) { syncUpdateIgnorerContent: params => ipcRenderer.invoke("syncUpdateIgnorerContent", params), syncFetchIgnorerContent: params => ipcRenderer.invoke("syncFetchIgnorerContent", params), updateNotificationCount: count => ipcRenderer.invoke("updateNotificationCount", count), + updateErrorCount: count => ipcRenderer.invoke("updateErrorCount", count), + updateWarningCount: count => ipcRenderer.invoke("updateWarningCount", count), + updateIsSyncing: isSyncing => ipcRenderer.invoke("updateIsSyncing", isSyncing), toggleAutoLaunch: enabled => ipcRenderer.invoke("toggleAutoLaunch", enabled), installUpdate: () => ipcRenderer.invoke("installUpdate"), isWinFSPInstalled: () => ipcRenderer.invoke("isWinFSPInstalled"), @@ -214,6 +222,8 @@ if (env.isBrowser || env.isElectron) { networkDriveStats: () => ipcRenderer.invoke("networkDriveStats"), syncUpdatePairs: params => ipcRenderer.invoke("syncUpdatePairs", params), tryingToSyncDesktop: path => ipcRenderer.invoke("tryingToSyncDesktop", path), - isPathSyncedByICloud: path => ipcRenderer.invoke("isPathSyncedByICloud", path) + isPathSyncedByICloud: path => ipcRenderer.invoke("isPathSyncedByICloud", path), + setMinimizeToTray: minimizeToTray => ipcRenderer.invoke("setMinimizeToTray", minimizeToTray), + setStartMinimized: startMinimized => ipcRenderer.invoke("setStartMinimized", startMinimized) } satisfies DesktopAPI) } diff --git a/src/types.ts b/src/types.ts index a13e426..969702c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -141,3 +141,10 @@ export type WorkerMessage = type: "sync" data: SyncMessage } + +export type TrayState = { + notificationCount: number + isSyncing: boolean + warningCount: number + errorCount: number +}