Merge pull request 'Templates' (#1) from templating into master
Some checks failed
publish / publish-tauri (, ubuntu-22.04) (push) Failing after 1m25s
Reviewed-on: #1
BIN
app-icon.png
Normal file
|
After Width: | Height: | Size: 113 MiB |
136
bun.lock
@ -1,5 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "smoothie",
|
||||
@ -18,6 +19,7 @@
|
||||
"@tauri-apps/plugin-window-state": "~2",
|
||||
"@webtui/css": "^0.1.6",
|
||||
"figlet": "^1.11.0",
|
||||
"svelte-dropzone-runes": "^1.0.7",
|
||||
"svelte-splitpanes": "^8.0.12",
|
||||
"svelte-tabs": "^1.1.0",
|
||||
},
|
||||
@ -99,17 +101,17 @@
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
||||
|
||||
"@eslint/compat": ["@eslint/compat@2.0.2", "", { "dependencies": { "@eslint/core": "^1.1.0" }, "peerDependencies": { "eslint": "^8.40 || 9 || 10" }, "optionalPeers": ["eslint"] }, "sha512-pR1DoD0h3HfF675QZx0xsyrsU8q70Z/plx7880NOhS02NuWLgBCOMDL787nUeQ7EWLkxv3bPQJaarjcPQb2Dwg=="],
|
||||
"@eslint/compat": ["@eslint/compat@2.1.0", "", { "dependencies": { "@eslint/core": "^1.2.1" }, "peerDependencies": { "eslint": "^8.40 || 9 || 10" }, "optionalPeers": ["eslint"] }, "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
|
||||
"@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="],
|
||||
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@1.1.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw=="],
|
||||
"@eslint/core": ["@eslint/core@1.2.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.4", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.3", "strip-json-comments": "^3.1.1" } }, "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ=="],
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.39.3", "", {}, "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw=="],
|
||||
"@eslint/js": ["@eslint/js@9.39.4", "", {}, "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
|
||||
|
||||
@ -135,6 +137,12 @@
|
||||
|
||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||
|
||||
"@publint/pack": ["@publint/pack@0.1.4", "", {}, "sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ=="],
|
||||
|
||||
"@rollup/plugin-typescript": ["@rollup/plugin-typescript@12.3.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.14.0||^3.0.0||^4.0.0", "tslib": "*", "typescript": ">=3.7.0" }, "optionalPeers": ["rollup", "tslib"] }, "sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big=="],
|
||||
|
||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.4.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
|
||||
@ -187,59 +195,63 @@
|
||||
|
||||
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
|
||||
|
||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.9", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA=="],
|
||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.10", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA=="],
|
||||
|
||||
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.10", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew=="],
|
||||
|
||||
"@sveltejs/kit": ["@sveltejs/kit@2.53.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.3", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-M+MqAvFve12T1HWws/2npP/s3hFtyjw3GB/OXW/8a1jZBk48qnvPJrtgE+VOMc3RnjUMxc4mv/vQ73nvj2uNMg=="],
|
||||
"@sveltejs/kit": ["@sveltejs/kit@2.64.0", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.9", "@types/cookie": "^0.6.0", "acorn": "^8.16.0", "cookie": "^0.6.0", "devalue": "^5.8.1", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-24MXA/xyugUqJd09DD4v4bLd4k7FaYhdBck/pTXiu3XFtDBcwXYpJc1SO1+lqdjkNBUo1r4eek5FS7cfzBQUmA=="],
|
||||
|
||||
"@sveltejs/load-config": ["@sveltejs/load-config@0.1.1", "", {}, "sha512-BXXm+VOH/9X4N7Dd1iZ2MqA1h7M+9i2noI8QYuLDY8QcN2WHYn7D/VK/+IJNfcAmRw7ACNJ538UT9GXIhnBTiA=="],
|
||||
|
||||
"@sveltejs/package": ["@sveltejs/package@2.5.8", "", { "dependencies": { "chokidar": "^5.0.0", "kleur": "^4.1.5", "sade": "^1.8.1", "semver": "^7.5.4", "svelte2tsx": "~0.7.55" }, "peerDependencies": { "svelte": "^3.44.0 || ^4.0.0 || ^5.0.0-next.1" }, "bin": { "svelte-package": "svelte-package.js" } }, "sha512-zeBbsXYvHiBu56v4gJaGQoEHzg96w0E1j3dOMX8vo56s6vI5eQ57ZEZhudjwjnegnVitRRu5MrmhO0eNvaonIw=="],
|
||||
|
||||
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.1.1", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.0.6" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ=="],
|
||||
|
||||
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
|
||||
|
||||
"@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
"@tauri-apps/api": ["@tauri-apps/api@2.11.0", "", {}, "sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA=="],
|
||||
|
||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.10.0", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.0", "@tauri-apps/cli-darwin-x64": "2.10.0", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0", "@tauri-apps/cli-linux-arm64-gnu": "2.10.0", "@tauri-apps/cli-linux-arm64-musl": "2.10.0", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-musl": "2.10.0", "@tauri-apps/cli-win32-arm64-msvc": "2.10.0", "@tauri-apps/cli-win32-ia32-msvc": "2.10.0", "@tauri-apps/cli-win32-x64-msvc": "2.10.0" }, "bin": { "tauri": "tauri.js" } }, "sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q=="],
|
||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.11.2", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.11.2", "@tauri-apps/cli-darwin-x64": "2.11.2", "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.2", "@tauri-apps/cli-linux-arm64-gnu": "2.11.2", "@tauri-apps/cli-linux-arm64-musl": "2.11.2", "@tauri-apps/cli-linux-riscv64-gnu": "2.11.2", "@tauri-apps/cli-linux-x64-gnu": "2.11.2", "@tauri-apps/cli-linux-x64-musl": "2.11.2", "@tauri-apps/cli-win32-arm64-msvc": "2.11.2", "@tauri-apps/cli-win32-ia32-msvc": "2.11.2", "@tauri-apps/cli-win32-x64-msvc": "2.11.2" }, "bin": { "tauri": "tauri.js" } }, "sha512-bk3HemqvGRoy+5D/dVMUQHKMYLglD0jVnMm/0iGMH6ufZ+p8r14m6BpIixwij3PBvZdvORUp1YifTD8QxVZ1Nw=="],
|
||||
|
||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA=="],
|
||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.11.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+4UZzLt+eOAEQCwgd+TqKgyUJMrvx+BgdXLLaqJYmPqzP+nE6YZr/hY6CWLYGQb8jFn99jEkmC6uA3tNvamA1w=="],
|
||||
|
||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q=="],
|
||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.11.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-VjYYtZUPqDMLutSfJEyxFE3Bz+DPi7c8wC3imckgvciLDZLq4qwKJxBicg0BXGhXjJsl8vKWgWRFNMPELQ+Xyg=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.0", "", { "os": "linux", "cpu": "arm" }, "sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g=="],
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.11.2", "", { "os": "linux", "cpu": "arm" }, "sha512-yMemD6f4i95AQriS8EazyOFzbE34yjnP16i3IOzpHGQvBoy2DjypFMFBq0NtPuITURv/cOGguRtHR5d79/9CSA=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA=="],
|
||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.11.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-cgI91D2wL8GSgoWwZXDqt+DwnuZCP2/bz03QAE4TrhgAKIsrB4hX26W/H1EONPUUNkqrsgeCD0wU6pcNjV/5kw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA=="],
|
||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.11.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-X1rm0BERqAAggtYTESSgXrS3sz4Sb/OiPiz54UqISlXW+GkR3vNIGnsy/lejNmoXGVqri3Q53BCfQiclOIyRPw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.0", "", { "os": "linux", "cpu": "none" }, "sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw=="],
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.11.2", "", { "os": "linux", "cpu": "none" }, "sha512-usbMLJbT3KtkOrBMDVeGYNM35aTHXx38SJSzTMSqqjeUIOQ+iVPjb2yAGNAE+KqmBbAx4FOFIyMeKXx2M/JKGQ=="],
|
||||
|
||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng=="],
|
||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.11.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Ru4gwJKPG0ctVGchRGpRup4Y4lW2SSfFnrbQcyHhCliKy4g8Qz97TrUgCur4CbWyAgKxvGh3SjrkA0LDYzDGiw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.0", "", { "os": "linux", "cpu": "x64" }, "sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q=="],
|
||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.11.2", "", { "os": "linux", "cpu": "x64" }, "sha512-eUm7T6clN1MMmNSRQ9gaWsQdyehQx2Gmn5hht/QUlqZQI/qcP2OJK5dnaxqwFzCr2HdsEo9ydxaqcS1oJzMvUw=="],
|
||||
|
||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g=="],
|
||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.11.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-HeeZW80jU+gVTOEX4X/hC6NVSAdDVXajwP5fxIZ/3z9WvUC7qrudX2GMTilYq6Dg0e0sk0XgsAJD1hZ5wPBXUA=="],
|
||||
|
||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A=="],
|
||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.11.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YhjQNZcXfbkCLyazSv1nPnJ9iRFE1wm6kc51FDbU10/Dk09io+6PAGMLjkxnX2GdM0qMnDmTjstY8mTDVvtKeA=="],
|
||||
|
||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ=="],
|
||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.11.2", "", { "os": "win32", "cpu": "x64" }, "sha512-d2JchlFIpZevZVReyqhQOekJmb1UH3rhZ5VX6sH3ty9ETE0TKQavpihvoScUXfKKpW6HZC0MrFGRU0ZtD+w3gA=="],
|
||||
|
||||
"@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.6.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg=="],
|
||||
"@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.7.1", "", { "dependencies": { "@tauri-apps/api": "^2.11.0" } }, "sha512-OK1UBXYt+ojcmxMktzzuyonYIFta8CmAASpX+CA+DTGK24KlHjhYI6x2iOJ/TjZF4N7/ACK1oFmEOjIY9IhzOQ=="],
|
||||
|
||||
"@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.5", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA=="],
|
||||
"@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.5.1", "", { "dependencies": { "@tauri-apps/api": "^2.11.0" } }, "sha512-9Lz+Jopp6QyeEWhlpkMx4R/+P9HgR+AVAI4vOZhlT8Xaymtz8iVI/Ov984/XTqgJz/5gz5NretqPB/XEMS3NhQ=="],
|
||||
|
||||
"@tauri-apps/plugin-http": ["@tauri-apps/plugin-http@2.5.7", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-+F2lEH/c9b0zSsOXKq+5hZNcd9F4IIKCK1T17RqMwpCmVnx2aoqY8yIBccCd25HTYUb3j6NPVbRax/m00hKG8A=="],
|
||||
"@tauri-apps/plugin-http": ["@tauri-apps/plugin-http@2.5.9", "", { "dependencies": { "@tauri-apps/api": "^2.11.0" } }, "sha512-lCiY0+vs4HvIUSvZrBs8TC3TiCB0MOPRmiUjTq4prW7SlcJE2jdLeT6KBsJrT9Tlplufl7W1pY6SFAO3gCWxDA=="],
|
||||
|
||||
"@tauri-apps/plugin-notification": ["@tauri-apps/plugin-notification@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg=="],
|
||||
|
||||
"@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ=="],
|
||||
"@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.4", "", { "dependencies": { "@tauri-apps/api": "^2.11.0" } }, "sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ=="],
|
||||
|
||||
"@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="],
|
||||
|
||||
"@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.5", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg=="],
|
||||
|
||||
"@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A=="],
|
||||
"@tauri-apps/plugin-store": ["@tauri-apps/plugin-store@2.4.3", "", { "dependencies": { "@tauri-apps/api": "^2.11.0" } }, "sha512-9LWPj9yMphRi9czEtUv87XHbl1b6xgd9EXpPrUnq6nG7+nbtoF84d4Kwz9xhAv/Hf30sr58pq7EOlyI936y8qw=="],
|
||||
|
||||
"@tauri-apps/plugin-updater": ["@tauri-apps/plugin-updater@2.10.0", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ=="],
|
||||
"@tauri-apps/plugin-updater": ["@tauri-apps/plugin-updater@2.10.1", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA=="],
|
||||
|
||||
"@tauri-apps/plugin-upload": ["@tauri-apps/plugin-upload@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ebhsqXmiELnpKu2p46EZG14UKxvbVP28BpJBiHzR+quWVrMxm40518PXTDlXXcJUW5CkbmP/6RL5ERSVXBL8sQ=="],
|
||||
|
||||
@ -251,11 +263,11 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@22.19.13", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-akNQMv0wW5uyRpD2v2IEyRSZiR+BeGuoB6L310EgGObO44HSMNT8z1xzio28V8qOrgYaopIDNA18YgdXd+qTiw=="],
|
||||
"@types/node": ["@types/node@22.19.20", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw=="],
|
||||
|
||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||
|
||||
"@webtui/css": ["@webtui/css@0.1.6", "", {}, "sha512-pYQ7wE5R2ZC4Suj/BtHg5oG1HPhX+RXfFPh/pn8b+Eb+GHmL7rT8RrKkywLgtExNBD0kdqrEDHAr7pjs6PNNBg=="],
|
||||
"@webtui/css": ["@webtui/css@0.1.7", "", {}, "sha512-iPK/gRM0EPBSa1tyJINm2pRPuKoT1GryN0Qljar+gDaKHJPNExKvOmnVKk91JpsTUb8qXZd+ggSJJjns1fXLNg=="],
|
||||
|
||||
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
|
||||
|
||||
@ -299,21 +311,25 @@
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"dedent-js": ["dedent-js@1.0.1", "", {}, "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||
|
||||
"devalue": ["devalue@5.6.3", "", {}, "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg=="],
|
||||
"devalue": ["devalue@5.8.1", "", {}, "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw=="],
|
||||
|
||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.39.3", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.3", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg=="],
|
||||
"eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
|
||||
|
||||
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
|
||||
|
||||
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.15.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.4.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0 || ^10.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-QKB7zqfuB8aChOfBTComgDptMf2yxiJx7FE04nneCmtQzgTHvY8UJkuh8J2Rz7KB9FFV9aTHX6r7rdYGvG8T9Q=="],
|
||||
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.19.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.7.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0 || ^10.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-t3rNaZeXz4d2gG4uJyMEYfJCFKf22+SWbSizIIXIWKu4wM+XPLiMWuSSr/C5821JmFeN9ogK+eExbG+z+twyxw=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||
|
||||
@ -325,12 +341,14 @@
|
||||
|
||||
"esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
|
||||
|
||||
"esrap": ["esrap@2.2.3", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ=="],
|
||||
"esrap": ["esrap@2.2.11", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-gPdx+I+BjYEinNMQaBXFjbaJVyoPMU4ZODg5mE+M4DqVG9VusAVHHjcBX+zqyITlI0DIARwDMMzZwAWj36dRoQ=="],
|
||||
|
||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
@ -345,6 +363,8 @@
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"file-selector": ["file-selector@2.1.2", "", { "dependencies": { "tslib": "^2.7.0" } }, "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig=="],
|
||||
|
||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
@ -353,18 +373,24 @@
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="],
|
||||
"globals": ["globals@17.6.0", "", {}, "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
|
||||
|
||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
@ -417,12 +443,16 @@
|
||||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
@ -439,20 +469,26 @@
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
||||
"prettier": ["prettier@3.8.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q=="],
|
||||
|
||||
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.5.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-2lLO/7EupnjO/95t+XZesXs8Bf3nYLIDfCo270h5QWbj/vjLqmrQ1LiRk9LPggxSDsnVYfehamZNf+rgQYApZg=="],
|
||||
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.5.2", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-ItFouLvzSFE3ulNl4DKoWM3BGcbDCNVpIyy/Y3F2gC3aNiGLxtFUdffVqO5Z5hhYG+DFT5KULWaxmeFFpdbvaQ=="],
|
||||
|
||||
"publint": ["publint@0.3.21", "", { "dependencies": { "@publint/pack": "^0.1.4", "package-manager-detector": "^1.6.0", "picocolors": "^1.1.1", "sade": "^1.8.1" }, "bin": { "publint": "src/cli.js" } }, "sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||
|
||||
"resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
|
||||
"rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
|
||||
|
||||
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||
|
||||
"scule": ["scule@1.3.0", "", {}, "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="],
|
||||
|
||||
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||
|
||||
"set-cookie-parser": ["set-cookie-parser@3.0.1", "", {}, "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q=="],
|
||||
@ -469,20 +505,28 @@
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"svelte": ["svelte@5.53.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.3", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-YkqERnF05g8KLdDZwZrF8/i1eSbj6Eoat8Jjr2IfruZz9StLuBqo8sfCSzjosNKd+ZrQ8DkKZDjpO5y3ht1Pow=="],
|
||||
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||
|
||||
"svelte-check": ["svelte-check@4.4.3", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-4HtdEv2hOoLCEsSXI+RDELk9okP/4sImWa7X02OjMFFOWeSdFF3NFy3vqpw0z+eH9C88J9vxZfUXz/Uv2A1ANw=="],
|
||||
"svelte": ["svelte@5.56.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.10", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.11", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-w7JvrM5IFl5cmfbY0TLik9o7mjRUJmRMhOR51tBPu708Gr/MjbGs7VnJnr/B0CaXeI4vtnOh7RKxDr0cwhMdDA=="],
|
||||
|
||||
"svelte-eslint-parser": ["svelte-eslint-parser@1.5.1", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0", "semver": "^7.7.2" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-UbY7DYoDg+x4AKLUcX5xWuEWylgmm8ZD2Z89YT/AK6Wm/ckeMTnOMwr6AVC99znXbRC26xzWEPhSgmB62E07Gg=="],
|
||||
"svelte-check": ["svelte-check@4.6.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "@sveltejs/load-config": "0.1.1", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-KhVnDFDSid57mmZtHz8gfW8AAGylOZ0vPnOIzVmAL+urzwK8sBYXRss953gD8T0OdgAQ11mdWhE6uadmtOz8TQ=="],
|
||||
|
||||
"svelte-dropzone-runes": ["svelte-dropzone-runes@1.0.7", "", { "dependencies": { "@rollup/plugin-typescript": "^12.1.2", "@sveltejs/package": "^2.0.0", "file-selector": "^2.1.2", "publint": "^0.3.11" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-l2Ptc4iHYlo+aYvTVPd1qJilC/Oh3BI8KX4K22C7HQTbiXS0UkWL9Oks5Vl0A4V83QEYJBDZCD+VnlVyBbMJrQ=="],
|
||||
|
||||
"svelte-eslint-parser": ["svelte-eslint-parser@1.8.0", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0", "semver": "^7.7.2" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-mikR1qwIVy3t5WthUoAXkMwxkXvabZP9FJgdx35Ei7EbGWmctva1Pih16Koeor/bdNNq8NXHlwKGS6NkYTawLg=="],
|
||||
|
||||
"svelte-splitpanes": ["svelte-splitpanes@8.0.12", "", { "peerDependencies": { "svelte": "^5.43.0" } }, "sha512-HJ07HgbtY0Q/35TEuJquGy47dtgCVavV7ay9r1FhWRx3boyUs3RpeiHlwMKliznCKy2ZotNeT+8GG+mIoNjgRA=="],
|
||||
|
||||
"svelte-tabs": ["svelte-tabs@1.1.0", "", {}, "sha512-bCynxgET2uvqpB6xf/dVyqHjzmumRURQyh2QqXlrki8NxzO7h2WghF8qgpb5qeB5NTX1bMU+9Q5Hf5ey2WLaMg=="],
|
||||
|
||||
"svelte2tsx": ["svelte2tsx@0.7.56", "", { "dependencies": { "dedent-js": "^1.0.1", "scule": "^1.3.0" }, "peerDependencies": { "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", "typescript": "^4.9.4 || ^5.0.0 || ^6.0.0" } }, "sha512-NTvqqL+goYlW8gWNajk81L07+uu7jw5V2m1Az5MZbYm3GEydcHXh+uTrLHM9SuGuaqCtF90vlMXkOVBotfH94g=="],
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||
|
||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"typescript": ["typescript@5.6.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],
|
||||
@ -493,7 +537,7 @@
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
|
||||
"vite": ["vite@6.4.3", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A=="],
|
||||
|
||||
"vitefu": ["vitefu@1.1.2", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw=="],
|
||||
|
||||
@ -515,8 +559,22 @@
|
||||
|
||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"@sveltejs/package/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
|
||||
|
||||
"@tauri-apps/plugin-notification/@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"@tauri-apps/plugin-os/@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"@tauri-apps/plugin-shell/@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"@tauri-apps/plugin-upload/@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"@tauri-apps/plugin-window-state/@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||
|
||||
"eslint/@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"eslint-plugin-svelte/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
|
||||
|
||||
"@sveltejs/package/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
|
||||
}
|
||||
}
|
||||
|
||||
57
package.json
@ -15,40 +15,41 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-dialog": "~2",
|
||||
"@tauri-apps/plugin-fs": "~2",
|
||||
"@tauri-apps/plugin-http": "^2.5.7",
|
||||
"@tauri-apps/plugin-notification": "~2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
"@tauri-apps/api": "^2.11.0",
|
||||
"@tauri-apps/plugin-dialog": "~2.7.1",
|
||||
"@tauri-apps/plugin-fs": "~2.5.1",
|
||||
"@tauri-apps/plugin-http": "^2.5.9",
|
||||
"@tauri-apps/plugin-notification": "~2.3.3",
|
||||
"@tauri-apps/plugin-opener": "^2.5.4",
|
||||
"@tauri-apps/plugin-os": "^2.3.2",
|
||||
"@tauri-apps/plugin-shell": "~2",
|
||||
"@tauri-apps/plugin-store": "~2",
|
||||
"@tauri-apps/plugin-updater": "~2",
|
||||
"@tauri-apps/plugin-upload": "~2",
|
||||
"@tauri-apps/plugin-window-state": "~2",
|
||||
"@webtui/css": "^0.1.6",
|
||||
"@tauri-apps/plugin-shell": "~2.3.5",
|
||||
"@tauri-apps/plugin-store": "~2.4.3",
|
||||
"@tauri-apps/plugin-updater": "~2.10.1",
|
||||
"@tauri-apps/plugin-upload": "~2.4.0",
|
||||
"@tauri-apps/plugin-window-state": "~2.4.1",
|
||||
"@webtui/css": "^0.1.7",
|
||||
"figlet": "^1.11.0",
|
||||
"svelte-dropzone-runes": "^1.0.7",
|
||||
"svelte-splitpanes": "^8.0.12",
|
||||
"svelte-tabs": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^2.0.2",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@sveltejs/adapter-static": "^3.0.6",
|
||||
"@sveltejs/kit": "^2.9.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@types/node": "^22",
|
||||
"eslint": "^9.39.2",
|
||||
"@eslint/compat": "^2.1.0",
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.64.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.1.1",
|
||||
"@tauri-apps/cli": "^2.11.2",
|
||||
"@types/node": "^22.19.20",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.14.0",
|
||||
"globals": "^17.3.0",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.4.1",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "~5.6.2",
|
||||
"vite": "^6.0.3"
|
||||
"eslint-plugin-svelte": "^3.19.0",
|
||||
"globals": "^17.6.0",
|
||||
"prettier": "^3.8.4",
|
||||
"prettier-plugin-svelte": "^3.5.2",
|
||||
"svelte": "^5.56.3",
|
||||
"svelte-check": "^4.6.0",
|
||||
"typescript": "~5.6.3",
|
||||
"vite": "^6.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +1,52 @@
|
||||
{
|
||||
"identifier": "desktop-capability",
|
||||
"platforms": [
|
||||
"macOS",
|
||||
"windows",
|
||||
"linux"
|
||||
],
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-hide",
|
||||
"core:window:allow-show",
|
||||
"core:window:allow-is-visible",
|
||||
"core:window:allow-destroy",
|
||||
"core:default",
|
||||
"opener:default",
|
||||
"window-state:default",
|
||||
"dialog:allow-open",
|
||||
"dialog:allow-confirm",
|
||||
"fs:allow-app-read-recursive",
|
||||
"fs:allow-app-write-recursive",
|
||||
"opener:allow-open-path",
|
||||
"fs:allow-mkdir",
|
||||
{
|
||||
"identifier": "fs:scope",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$LOCALDATA/applications/**"
|
||||
},
|
||||
{
|
||||
"path": "$LOCALDATA/applications"
|
||||
},
|
||||
{
|
||||
"path": "$LOCALDATA/applications/*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shell:allow-spawn",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*.blender.org"
|
||||
}
|
||||
]
|
||||
},
|
||||
"notification:default",
|
||||
"os:default",
|
||||
"store:default",
|
||||
"shell:default",
|
||||
"upload:default",
|
||||
"updater:default"
|
||||
]
|
||||
"identifier": "desktop-capability",
|
||||
"platforms": ["macOS", "windows", "linux"],
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:window:default",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-hide",
|
||||
"core:window:allow-show",
|
||||
"core:window:allow-is-visible",
|
||||
"core:window:allow-destroy",
|
||||
"core:default",
|
||||
"opener:default",
|
||||
"window-state:default",
|
||||
"dialog:allow-open",
|
||||
"dialog:allow-confirm",
|
||||
"fs:allow-app-read-recursive",
|
||||
"fs:allow-app-write-recursive",
|
||||
"opener:allow-open-path",
|
||||
"fs:allow-mkdir",
|
||||
{
|
||||
"identifier": "fs:scope",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$LOCALDATA/applications/**"
|
||||
},
|
||||
{
|
||||
"path": "$LOCALDATA/applications"
|
||||
},
|
||||
{
|
||||
"path": "$LOCALDATA/applications/*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shell:allow-spawn",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*.blender.org"
|
||||
}
|
||||
]
|
||||
},
|
||||
"notification:default",
|
||||
"os:default",
|
||||
"store:default",
|
||||
"shell:default",
|
||||
"upload:default",
|
||||
"updater:default"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 974 B After Width: | Height: | Size: 2.3 KiB |
BIN
src-tauri/icons/64x64.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 903 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
</adaptive-icon>
|
||||
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 117 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#fff</color>
|
||||
</resources>
|
||||
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 156 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@1x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@2x-1.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@2x.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@3x.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@1x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@2x-1.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@2x.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@3x.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@1x.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@2x-1.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@2x.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@3x.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src-tauri/icons/ios/AppIcon-512@2x.png
Normal file
|
After Width: | Height: | Size: 496 KiB |
BIN
src-tauri/icons/ios/AppIcon-60x60@2x.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src-tauri/icons/ios/AppIcon-60x60@3x.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
src-tauri/icons/ios/AppIcon-76x76@1x.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
src-tauri/icons/ios/AppIcon-76x76@2x.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
@ -12,8 +12,8 @@
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"decorations": true,
|
||||
"title": "smoothie",
|
||||
"dragDropEnabled": true,
|
||||
"width": 1024,
|
||||
"height": 576,
|
||||
"maxHeight": 1080,
|
||||
|
||||
109
src/lib/components/Dropzone.svelte
Normal file
@ -0,0 +1,109 @@
|
||||
<script>
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||
import { onMount } from 'svelte';
|
||||
import { addTemplateFile } from '$lib/file_utils';
|
||||
import Popup from '$lib/components/Popup.svelte';
|
||||
let dragging = $state(false);
|
||||
let hasBlend = $state(false);
|
||||
let dropzoneEl = $state(null);
|
||||
|
||||
let { version } = $props();
|
||||
|
||||
let successPopup;
|
||||
let errorPopup;
|
||||
|
||||
onMount(() => {
|
||||
const win = getCurrentWindow();
|
||||
let unlisten = () => {};
|
||||
|
||||
win
|
||||
.onDragDropEvent((event) => {
|
||||
if (!dropzoneEl) return;
|
||||
|
||||
const payload = event.payload;
|
||||
|
||||
if (payload.type === 'enter') {
|
||||
hasBlend = payload.paths.some((p) => p.endsWith('.blend'));
|
||||
if (!hasBlend) return;
|
||||
}
|
||||
|
||||
if (payload.type === 'leave') {
|
||||
dragging = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 'enter', 'over', and 'drop' all have position data
|
||||
const rect = dropzoneEl.getBoundingClientRect();
|
||||
const scale = window.devicePixelRatio || 1;
|
||||
const cssX = payload.position.x / scale;
|
||||
const cssY = payload.position.y / scale;
|
||||
|
||||
const isInside =
|
||||
cssX >= rect.left && cssX <= rect.right && cssY >= rect.top && cssY <= rect.bottom;
|
||||
|
||||
if (payload.type === 'over') {
|
||||
dragging = hasBlend && isInside;
|
||||
} else if (payload.type === 'enter') {
|
||||
dragging = isInside;
|
||||
} else if (payload.type === 'drop') {
|
||||
dragging = false;
|
||||
if (hasBlend && isInside) {
|
||||
const blendFiles = payload.paths.filter((p) => p.endsWith('.blend'));
|
||||
if (blendFiles.length > 0) {
|
||||
console.log('Dropped Blender files:', blendFiles);
|
||||
blendFiles.forEach(async (file) => {
|
||||
if (version) {
|
||||
const result = await addTemplateFile(version, file);
|
||||
if (result.success) {
|
||||
successPopup.pop(result.message, 3000);
|
||||
} else {
|
||||
errorPopup.pop(result.message, 4000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.then((fn) => {
|
||||
unlisten = fn;
|
||||
});
|
||||
|
||||
return () => unlisten();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="dropzone" class:dragging bind:this={dropzoneEl}>Drop Blender Files</div>
|
||||
|
||||
<Popup bind:this={successPopup} type="confirm" />
|
||||
<Popup bind:this={errorPopup} type="error" />
|
||||
|
||||
<style>
|
||||
.dropzone {
|
||||
height: 3rem;
|
||||
|
||||
width: 100%;
|
||||
border-color: var(--light-accent);
|
||||
border-width: 3px;
|
||||
border-style: solid;
|
||||
border-radius: 5px;
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--light-accent);
|
||||
transition:
|
||||
border-color 0.15s,
|
||||
color 0.15s;
|
||||
cursor: pointer;
|
||||
transition: 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.dropzone.dragging {
|
||||
height: 5rem;
|
||||
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
}
|
||||
</style>
|
||||
@ -1,50 +1,84 @@
|
||||
<script>
|
||||
import VersionCard from './VersionCard.svelte';
|
||||
import TemplateCard from './TemplateCard.svelte';
|
||||
|
||||
import { send, receive } from '$lib/transition.js';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { selectedVersionStore } from '$lib/library.js';
|
||||
import { Splitpanes, Pane } from 'svelte-splitpanes';
|
||||
|
||||
let selectedVersion = $state(null);
|
||||
|
||||
selectedVersionStore.subscribe((version) => {
|
||||
selectedVersion = version;
|
||||
});
|
||||
|
||||
let { installedVersions } = $props();
|
||||
import '@webtui/css/base.css';
|
||||
import '@webtui/css/utils/box.css';
|
||||
import Dropzone from './Dropzone.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
let favourites = $derived(installedVersions?.filter((v) => v.favourite) || []);
|
||||
let installed = $derived(installedVersions?.filter((v) => !v.favourite) || []);
|
||||
</script>
|
||||
|
||||
<h2>Favourites</h2>
|
||||
<Splitpanes id="split">
|
||||
<Pane>
|
||||
<h2>Favourites</h2>
|
||||
|
||||
<div id="container">
|
||||
<div id="library">
|
||||
{#if favourites.length}
|
||||
{#each favourites as version (version.version)}
|
||||
<div
|
||||
animate:flip={{ duration: 200 }}
|
||||
in:receive={{ key: version.version }}
|
||||
out:send={{ key: version.version }}
|
||||
>
|
||||
<VersionCard {version} />
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<p class="minor">No favourites</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Installed</h2>
|
||||
<div id="container">
|
||||
<div id="library">
|
||||
{#each installed as version (version.version)}
|
||||
<div
|
||||
animate:flip={{ duration: 200 }}
|
||||
in:receive={{ key: version.version }}
|
||||
out:send={{ key: version.version }}
|
||||
>
|
||||
<VersionCard {version} />
|
||||
<div id="container">
|
||||
<div id="library">
|
||||
{#if favourites.length}
|
||||
{#each favourites as version (version.version)}
|
||||
<div
|
||||
animate:flip={{ duration: 200 }}
|
||||
in:receive={{ key: version.version }}
|
||||
out:send={{ key: version.version }}
|
||||
>
|
||||
<VersionCard {version} {selectedVersion} />
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<p class="minor">No favourites</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Installed</h2>
|
||||
<div id="container">
|
||||
<div id="library">
|
||||
{#each installed as version (version.version)}
|
||||
<div
|
||||
animate:flip={{ duration: 200 }}
|
||||
in:receive={{ key: version.version }}
|
||||
out:send={{ key: version.version }}
|
||||
>
|
||||
<VersionCard {version} {selectedVersion} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<div id="templates">
|
||||
{#if selectedVersion}
|
||||
<h2>Blender {selectedVersion.version}</h2>
|
||||
<TemplateCard template={null} version={selectedVersion} />
|
||||
{#if selectedVersion?.templates.length > 0}
|
||||
{#each selectedVersion?.templates as template (template)}
|
||||
<div>
|
||||
<TemplateCard {template} version={selectedVersion} />
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<p class="minor">No templates</p>
|
||||
{/if}
|
||||
<Dropzone version={selectedVersion}></Dropzone>
|
||||
{/if}
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
|
||||
<style>
|
||||
.minor {
|
||||
@ -58,12 +92,27 @@
|
||||
max-height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#templates {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
padding: 0 0 0 1rem;
|
||||
}
|
||||
#library {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
min-height: 140px;
|
||||
padding-bottom: 1rem;
|
||||
overflow: visible;
|
||||
}
|
||||
:global(.splitpanes__pane) {
|
||||
background-color: unset !important;
|
||||
}
|
||||
:global(.splitpanes__splitter) {
|
||||
background-color: var(--light) !important;
|
||||
width: 0.5rem !important;
|
||||
border: none !important;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -88,6 +88,9 @@
|
||||
<style>
|
||||
.btncont {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.menu-container {
|
||||
height: 100%;
|
||||
|
||||
22
src/lib/components/MenuItem.svelte
Normal file
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
let { onclick, children } = $props();
|
||||
</script>
|
||||
|
||||
<button type="button" class="menu-item" {onclick}>{@render children?.()}</button>
|
||||
|
||||
<style>
|
||||
.menu-item {
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-family: var(--font);
|
||||
font-size: 1rem;
|
||||
color: var(--black);
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
.menu-item:hover {
|
||||
background-color: var(--light-accent);
|
||||
}
|
||||
</style>
|
||||
@ -1,10 +1,12 @@
|
||||
<script>
|
||||
import { fade, fly } from 'svelte/transition';
|
||||
|
||||
let { content = '', type = 'confirm' } = $props();
|
||||
let { type = 'confirm' } = $props();
|
||||
let open = $state(false);
|
||||
let message = $state('');
|
||||
|
||||
export function pop(resetTimeout = 0) {
|
||||
export function pop(msg = '', resetTimeout = 0) {
|
||||
message = msg;
|
||||
open = true;
|
||||
if (resetTimeout > 0) {
|
||||
setTimeout(() => {
|
||||
@ -17,7 +19,7 @@
|
||||
{#if open}
|
||||
<div in:fly={{ duration: 200, y: 100 }} out:fade class="popup {type}">
|
||||
<div class="popup-content">
|
||||
<p>{content}</p>
|
||||
<p>{message}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@ -35,4 +37,7 @@
|
||||
.confirm {
|
||||
background-color: var(--light-accent);
|
||||
}
|
||||
.error {
|
||||
background-color: var(--accent);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
async function handleDownload() {
|
||||
let result = await downloadBlenderVersion(selectedLink);
|
||||
if (result.success) {
|
||||
popup?.pop(2000);
|
||||
popup?.pop('Blender ' + selectedLink.version + ' has been installed', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,8 +29,7 @@
|
||||
let popup = $state();
|
||||
</script>
|
||||
|
||||
<Popup bind:this={popup} content={'Blender ' + selectedLink.version + ' has been installed'}
|
||||
></Popup>
|
||||
<Popup bind:this={popup}></Popup>
|
||||
<div class="download" class:full-width={downloading || installed}>
|
||||
<div class="selectVersion {downloading}">
|
||||
<select class:disabled={downloading && !installed} bind:value={linkIndex}>
|
||||
|
||||
85
src/lib/components/TemplateCard.svelte
Normal file
@ -0,0 +1,85 @@
|
||||
<script>
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Menu from '$lib/components/Menu.svelte';
|
||||
import MenuItem from '$lib/components/MenuItem.svelte';
|
||||
import { show } from '$lib/components/Dialog.svelte';
|
||||
import { deleteTemplate } from '$lib/library';
|
||||
|
||||
import { launchBlenderVersion } from '$lib/library';
|
||||
import { notify } from '$lib/notification.js';
|
||||
let { template, version } = $props();
|
||||
let templateName = $derived(
|
||||
template
|
||||
.split('/')
|
||||
.pop()
|
||||
.replace('.blend', '')
|
||||
.replace(/\b\w/g, (c) => c.toUpperCase())
|
||||
);
|
||||
|
||||
/**
|
||||
* Handles the deletion of a template.
|
||||
*
|
||||
* @param {string} template - The template file path to delete.
|
||||
*/
|
||||
async function handleDelete(template) {
|
||||
const prompt = await show({
|
||||
title: 'Delete Template',
|
||||
message: `This will delete the "${templateName}" template.`,
|
||||
buttons: ['Cancel', 'Continue'],
|
||||
type: 'warning'
|
||||
});
|
||||
if (prompt == 'Continue') {
|
||||
const result = await deleteTemplate(version, template);
|
||||
if (result.success) {
|
||||
notify(result.message, 3000);
|
||||
} else {
|
||||
notify(result.message, 4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if template == null}
|
||||
<div id="base-card">
|
||||
<Button fill={true} color="accent" onclick={() => launchBlenderVersion(version)}
|
||||
>Launch Base</Button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div id="template-card">
|
||||
<div class="leftmenu">
|
||||
<Menu>
|
||||
<MenuItem onclick={() => handleDelete(template)}>Delete</MenuItem>
|
||||
</Menu>
|
||||
{templateName}
|
||||
</div>
|
||||
<Button style="small" onclick={() => launchBlenderVersion(version, template)}>→</Button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
#base-card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
#template-card {
|
||||
height: 3rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
background-color: var(--light);
|
||||
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
width: 100%;
|
||||
transition: width 0.3s ease;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.leftmenu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,17 +1,21 @@
|
||||
<script>
|
||||
import Popup from '$lib/components/Popup.svelte';
|
||||
import {
|
||||
deleteVersion,
|
||||
launchBlenderVersion,
|
||||
toggleFavourite,
|
||||
registerVersion
|
||||
registerVersion,
|
||||
selectVersion
|
||||
} from '$lib/library';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Menu from '$lib/components/Menu.svelte';
|
||||
import { show } from '$lib/components/Dialog.svelte';
|
||||
import MenuItem from '$lib/components/MenuItem.svelte';
|
||||
|
||||
let { version } = $props();
|
||||
let popup = $state();
|
||||
import { show } from '$lib/components/Dialog.svelte';
|
||||
import { notify } from '$lib/notification.js';
|
||||
|
||||
let { version, selectedVersion } = $props();
|
||||
|
||||
let selected = $derived(version.version === selectedVersion?.version);
|
||||
|
||||
async function handleDelete() {
|
||||
const prompt = await show({
|
||||
@ -21,7 +25,12 @@
|
||||
type: 'warning'
|
||||
});
|
||||
if (prompt == 'Continue') {
|
||||
deleteVersion(version);
|
||||
const result = await deleteVersion(version);
|
||||
if (result.success) {
|
||||
notify(result.message, 3000);
|
||||
} else {
|
||||
notify(result.message, 4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,76 +42,77 @@
|
||||
type: 'info'
|
||||
});
|
||||
if (prompt == 'Continue') {
|
||||
popup.pop(1500);
|
||||
notify('Version ' + version.version + ' is now the default on your system', 1500);
|
||||
registerVersion(version);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Popup bind:this={popup} content="Version {version.version} is now the default on your system"
|
||||
></Popup>
|
||||
<div id="card">
|
||||
<div class="row">
|
||||
{version.version}
|
||||
<Button style="iconbutton" onclick={() => toggleFavourite(version)}
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
class="fav-btn {version.favourite ? 'fav' : ''}"
|
||||
viewBox="0 0 16 16"
|
||||
<div
|
||||
role="button"
|
||||
tabindex="0"
|
||||
onkeydown={() => {}}
|
||||
onclick={async () => {
|
||||
await selectVersion(version);
|
||||
}}
|
||||
ondblclick={async () => {
|
||||
console.log('double click', version);
|
||||
await launchBlenderVersion(version);
|
||||
}}
|
||||
id="card"
|
||||
class:selected
|
||||
>
|
||||
<Button style="iconbutton" onclick={() => toggleFavourite(version)}
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
class="fav-btn {version.favourite ? 'fav' : ''}"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M2 2v13.5a.5.5 0 0 0 .74.439L8 13.069l5.26 2.87A.5.5 0 0 0 14 15.5V2a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2"
|
||||
/>
|
||||
</svg>
|
||||
</Button>
|
||||
{version.version}
|
||||
<Menu>
|
||||
{#snippet children({ close })}
|
||||
<MenuItem
|
||||
onclick={async () => {
|
||||
await handleDelete();
|
||||
close();
|
||||
}}>Delete</MenuItem
|
||||
>
|
||||
<path
|
||||
d="M2 2v13.5a.5.5 0 0 0 .74.439L8 13.069l5.26 2.87A.5.5 0 0 0 14 15.5V2a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2"
|
||||
/>
|
||||
</svg>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<Button onclick={() => launchBlenderVersion(version)}>Launch</Button>
|
||||
<Menu>
|
||||
{#snippet children({ close })}
|
||||
<button
|
||||
type="button"
|
||||
class="menu-item"
|
||||
onclick={async () => {
|
||||
await handleDelete();
|
||||
close();
|
||||
}}>Delete</button
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="menu-item"
|
||||
onclick={async () => {
|
||||
await handleDefault();
|
||||
close();
|
||||
}}>Default</button
|
||||
>
|
||||
{/snippet}
|
||||
</Menu>
|
||||
</div>
|
||||
<MenuItem
|
||||
onclick={async () => {
|
||||
await handleDefault();
|
||||
close();
|
||||
}}>Default</MenuItem
|
||||
>
|
||||
{/snippet}
|
||||
</Menu>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
aspect-ratio: 1 / 0.7;
|
||||
width: 100%;
|
||||
min-width: 170px;
|
||||
max-width: 200px;
|
||||
background-color: var(--white);
|
||||
border-radius: 5px;
|
||||
background-color: var(--light);
|
||||
padding: 1rem;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#card.selected {
|
||||
background-color: var(--light-accent);
|
||||
}
|
||||
#card:hover {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: -2px;
|
||||
@ -113,18 +123,4 @@
|
||||
.fav-btn.fav {
|
||||
fill: var(--accent);
|
||||
}
|
||||
.menu-item {
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-family: var(--font);
|
||||
font-size: 1rem;
|
||||
color: var(--black);
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
.menu-item:hover {
|
||||
background-color: var(--light-accent);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -4,13 +4,14 @@ import {
|
||||
basename as pathBasename,
|
||||
dirname as pathDirname
|
||||
} from '@tauri-apps/api/path';
|
||||
import { stat, mkdir, readDir, copyFile, rename, remove } from '@tauri-apps/plugin-fs';
|
||||
import { stat, mkdir, readDir, copyFile, rename, remove, exists } from '@tauri-apps/plugin-fs';
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import baseicon from '$lib/assets/baseicon.png';
|
||||
import europa from '$lib/assets/fonts/Europa-Mono-Medium.otf';
|
||||
import { BASE_LIBRARY_DIR } from './settings';
|
||||
import figlet from 'figlet';
|
||||
import shadow from 'figlet/fonts/Classy';
|
||||
import { getInstalledVersions, getTemplatesDir } from './library';
|
||||
figlet.parseFont('Big', shadow);
|
||||
|
||||
/**
|
||||
@ -58,10 +59,10 @@ export async function createIcon(iconText) {
|
||||
|
||||
/**
|
||||
* Create a custom banner with version number next to the baseIcon image
|
||||
* @param {string} versionText - Version text to display
|
||||
* @param {string} text - Version text to display
|
||||
* @returns {Promise<Blob>} Promise resolving to a PNG blob of the banner
|
||||
*/
|
||||
export async function createBanner(versionText) {
|
||||
export async function createBanner(text) {
|
||||
// Create canvas element for banner
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
@ -82,11 +83,6 @@ export async function createBanner(versionText) {
|
||||
img.onload = resolve;
|
||||
});
|
||||
|
||||
// Calculate icon position (centered vertically, left-aligned)
|
||||
const iconSize = 70;
|
||||
const iconX = 20;
|
||||
const iconY = (canvas.height - iconSize) / 2;
|
||||
|
||||
// Add version text
|
||||
ctx.fillStyle = '#f5f5f5';
|
||||
ctx.textAlign = 'left';
|
||||
@ -102,7 +98,9 @@ export async function createBanner(versionText) {
|
||||
const textX = 20;
|
||||
const textY = canvas.height / 2;
|
||||
|
||||
const bannerText = await figlet.text(versionText + ' - Base', { font: 'Big' });
|
||||
const bannerText = await figlet.text(text, {
|
||||
font: 'Big'
|
||||
});
|
||||
const lines = bannerText.split('\n');
|
||||
const lineHeight = fontSize * 1.2;
|
||||
const startY = textY - (lines.length * lineHeight) / 2 + lineHeight / 2;
|
||||
@ -121,6 +119,32 @@ export async function createBanner(versionText) {
|
||||
}, 'image/png');
|
||||
});
|
||||
}
|
||||
|
||||
export async function addTemplateFile(version, filePath) {
|
||||
const newFileName = await pathBasename(filePath);
|
||||
const templateName = newFileName.replace(/\.blend$/i, '');
|
||||
const newTemplatePath = await join(await getTemplatesDir(version), templateName);
|
||||
|
||||
// Check for duplicate template name
|
||||
if (await exists(newTemplatePath)) {
|
||||
return { success: false, message: `Template "${templateName}" already exists` };
|
||||
}
|
||||
|
||||
const newTemplateFile = await join(newTemplatePath, 'startup.blend');
|
||||
await ensureDirectory(newTemplatePath);
|
||||
|
||||
try {
|
||||
await copyFile(filePath, newTemplateFile);
|
||||
} catch (error) {
|
||||
console.error('Error adding template file:', error);
|
||||
return { success: false, message: `Failed to add template: ${error.message || error}` };
|
||||
}
|
||||
|
||||
await getInstalledVersions();
|
||||
|
||||
return { success: true, message: `Template "${templateName}" added` };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create library directory structure if it doesn't exist
|
||||
* @param {string} libraryDir - Library directory path
|
||||
@ -131,10 +155,6 @@ export async function ensureLibraryStructure(libraryDir) {
|
||||
const baseDir = await join(libraryDir, BASE_LIBRARY_DIR);
|
||||
const blenderDir = await join(baseDir, 'blender');
|
||||
await mkdir(blenderDir, { recursive: true });
|
||||
|
||||
const templatesDir = await join(baseDir, 'templates');
|
||||
await mkdir(templatesDir, { recursive: true });
|
||||
|
||||
const configDir = await join(baseDir, 'config');
|
||||
await mkdir(configDir, { recursive: true });
|
||||
|
||||
@ -201,24 +221,6 @@ export async function ensureDirectory(path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the basename of a path (file or directory name)
|
||||
* @param {string} path - Full path
|
||||
* @returns {Promise<string>} Basename
|
||||
*/
|
||||
export async function basename(path) {
|
||||
return pathBasename(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directory name of a path
|
||||
* @param {string} path - Full path
|
||||
* @returns {Promise<string>} Directory name
|
||||
*/
|
||||
export async function dirname(path) {
|
||||
return pathDirname(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a file or directory recursively
|
||||
* @param {string} source - Source path
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { currentSettings } from '$lib/settings.js';
|
||||
import { createIcon, createBanner } from './file_utils';
|
||||
import { createIcon, createBanner, ensureDirectory } from './file_utils';
|
||||
import { platform } from '@tauri-apps/plugin-os';
|
||||
import { join, localDataDir } from '@tauri-apps/api/path';
|
||||
import { exists, stat, readDir, writeFile, remove } from '@tauri-apps/plugin-fs';
|
||||
@ -7,7 +7,6 @@ import { invoke } from '@tauri-apps/api/core';
|
||||
import { writable, get } from 'svelte/store';
|
||||
import { LazyStore } from '@tauri-apps/plugin-store';
|
||||
import { BASE_LIBRARY_DIR } from '$lib/settings.js';
|
||||
import { confirm } from '@tauri-apps/plugin-dialog';
|
||||
import { updateDownloadProgress } from './download';
|
||||
|
||||
/** INSTALLED BLENDER VERSION TYPE
|
||||
@ -17,13 +16,34 @@ import { updateDownloadProgress } from './download';
|
||||
* @property {string} executable - Path to Blender executable
|
||||
* @property {string} platform - Detected platform (windows, linux, macos)
|
||||
* @property {Date} [installDate] - Installation date (if available)
|
||||
* @property {Array<string>} [templates] - List of favourite scenes for this version
|
||||
*/
|
||||
|
||||
export const currentInstalledVersions = writable([]);
|
||||
export const installedVersionsStore = writable([]);
|
||||
export const selectedVersionStore = writable(null);
|
||||
const favouritesStore = new LazyStore('versions.json');
|
||||
|
||||
export async function selectVersion(version) {
|
||||
selectedVersionStore.set(version);
|
||||
}
|
||||
|
||||
export async function generateTemplateBanner(templateDir) {
|
||||
const bannerPath = `${templateDir}/banner.png`;
|
||||
if (await exists(bannerPath)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const templateName = templateDir.split('/').pop() || templateDir.split('\\').pop();
|
||||
const banner = await createBanner(templateName);
|
||||
const bannerBuffer = new Uint8Array(await banner.arrayBuffer());
|
||||
await writeFile(bannerPath, bannerBuffer);
|
||||
} catch (error) {
|
||||
console.error(`Failed to generate banner for template: ${templateDir}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateVersionBanner(version) {
|
||||
const bannerPath = `${version.path}/banner.png`;
|
||||
const bannerPath = await join(version.path, 'banner.png');
|
||||
if (await exists(bannerPath)) {
|
||||
return;
|
||||
}
|
||||
@ -183,6 +203,18 @@ MimeType=application/x-blender;
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeTemplate(templatePath) {
|
||||
if (await exists(templatePath)) {
|
||||
try {
|
||||
await remove(templatePath, { recursive: true });
|
||||
} catch (error) {
|
||||
console.warn(`Failed to remove template path: ${templatePath}`, error);
|
||||
}
|
||||
} else {
|
||||
console.warn(`Template path does not exist: ${templatePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeVersion(version) {
|
||||
if (await exists(version.path)) {
|
||||
try {
|
||||
@ -200,7 +232,7 @@ export async function removeVersion(version) {
|
||||
* @param {blenderVersion} version The version to toggle.
|
||||
*/
|
||||
export async function toggleFavourite(version) {
|
||||
const versions = get(currentInstalledVersions);
|
||||
const versions = get(installedVersionsStore);
|
||||
console.log();
|
||||
const versionObj = versions.find((v) => v.version === version.version);
|
||||
if (versionObj) {
|
||||
@ -208,11 +240,28 @@ export async function toggleFavourite(version) {
|
||||
} else {
|
||||
console.error('version not found', version);
|
||||
}
|
||||
currentInstalledVersions.set(versions);
|
||||
installedVersionsStore.set(versions);
|
||||
await favouritesStore.set(version.version, versionObj.favourite);
|
||||
await favouritesStore.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a template from the library.
|
||||
* @param {blenderVersion} version The version to remove the template from.
|
||||
* @param {string} template The name of the template to remove.
|
||||
*/
|
||||
export async function deleteTemplate(version, template) {
|
||||
const templatePath = await join(await getTemplatesDir(version), template);
|
||||
try {
|
||||
await removeTemplate(templatePath);
|
||||
await getInstalledVersions();
|
||||
return { success: true, message: `Template "${template}" deleted` };
|
||||
} catch (error) {
|
||||
console.error('Failed to delete template', error);
|
||||
return { success: false, message: `Failed to delete template: ${error.message || error}` };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a version and remove it from disk.
|
||||
* @param {blenderVersion} version The version to delete.
|
||||
@ -230,14 +279,15 @@ export async function deleteVersion(version) {
|
||||
await favouritesStore.save();
|
||||
|
||||
// Update the current installed versions list
|
||||
const versions = get(currentInstalledVersions);
|
||||
const versions = get(installedVersionsStore);
|
||||
const filteredVersions = versions.filter((v) => v.version !== version.version);
|
||||
currentInstalledVersions.set(filteredVersions);
|
||||
installedVersionsStore.set(filteredVersions);
|
||||
|
||||
console.log(`Successfully deleted version ${version.version}`);
|
||||
return { success: true, message: `Blender ${version.version} deleted` };
|
||||
} catch (error) {
|
||||
console.error(`Failed to delete version ${version.version}:`, error);
|
||||
throw error;
|
||||
return { success: false, message: `Failed to delete Blender ${version.version}: ${error.message || error}` };
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,13 +303,13 @@ export async function getInstalledVersions() {
|
||||
const settings = get(currentSettings);
|
||||
const libraryDir = settings.libraryDir;
|
||||
if (!libraryDir) {
|
||||
currentInstalledVersions.set([]);
|
||||
installedVersionsStore.set([]);
|
||||
return [];
|
||||
}
|
||||
const blenderLibraryPath = await join(libraryDir, BASE_LIBRARY_DIR, 'blender');
|
||||
|
||||
if (!exists(blenderLibraryPath)) {
|
||||
currentInstalledVersions.set([]);
|
||||
installedVersionsStore.set([]);
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -281,13 +331,22 @@ export async function getInstalledVersions() {
|
||||
const executable = await findBlenderExecutable(versionPath);
|
||||
if (executable) {
|
||||
const currentPlatform = platform();
|
||||
|
||||
// Get templates for this version
|
||||
|
||||
|
||||
let newVersion = {
|
||||
version,
|
||||
path: versionPath,
|
||||
executable,
|
||||
platform: currentPlatform,
|
||||
favourite: favourites[version] || false
|
||||
};
|
||||
favourite: favourites[version] || false,
|
||||
templates: []
|
||||
};
|
||||
|
||||
var templates = await getTemplates(newVersion);
|
||||
|
||||
newVersion.templates = templates;
|
||||
|
||||
//check if version has an icon, if not generate one
|
||||
await generateVersionIcon(newVersion);
|
||||
@ -308,17 +367,63 @@ export async function getInstalledVersions() {
|
||||
}
|
||||
}
|
||||
|
||||
currentInstalledVersions.set(versions);
|
||||
cleanupOrphanedDesktopFiles(versions);
|
||||
installedVersionsStore.set(versions);
|
||||
await cleanupOrphanedDesktopFiles(versions);
|
||||
const selectedVersion = get(selectedVersionStore);
|
||||
if (selectedVersion) {
|
||||
const refreshed = versions.find((v) => v.version === selectedVersion.version);
|
||||
selectedVersionStore.set(refreshed || selectedVersion);
|
||||
} else {
|
||||
if (versions.length > 0) {
|
||||
let favouriteVersion = versions.find((v) => v.favourite);
|
||||
if (favouriteVersion) {
|
||||
selectedVersionStore.set(favouriteVersion);
|
||||
} else {
|
||||
selectedVersionStore.set(versions[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return versions;
|
||||
} catch (error) {
|
||||
console.error('Error getting installed versions:', error);
|
||||
currentInstalledVersions.set([]);
|
||||
installedVersionsStore.set([]);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {blenderVersion} version
|
||||
* @returns {Promise<string[]>} List of .blend files paths in the templates directory
|
||||
*/
|
||||
export async function getTemplates(version) {
|
||||
try {
|
||||
const templatesDir = await getTemplatesDir(version)
|
||||
await ensureDirectory(templatesDir);
|
||||
|
||||
const entries = await readDir(templatesDir);
|
||||
const templates = [];
|
||||
|
||||
const ignoredDirs = ['Storyboarding', '2D_Animation', 'Sculpting', 'VFX', 'Video_Editing'];
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory && !ignoredDirs.includes(entry.name)) {
|
||||
const startupFile = await join(templatesDir, entry.name, 'startup.blend');
|
||||
await generateTemplateBanner(await join(templatesDir, entry.name));
|
||||
if (await exists(startupFile)) {
|
||||
templates.push(entry.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return templates;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Register a Blender version with the system.
|
||||
* @param {blenderVersion} version - The version object to launch
|
||||
@ -355,6 +460,53 @@ export async function registerVersion(version) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the templates directory for a given Blender version
|
||||
* @param {blenderVersion} version
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function getTemplatesDir(version) {
|
||||
|
||||
const versionNumber = version?.version;
|
||||
|
||||
|
||||
try {
|
||||
const templatesDir = await join(
|
||||
version.path,
|
||||
versionNumber.split('.').slice(0, 2).join('.'),
|
||||
'scripts',
|
||||
'startup',
|
||||
'bl_app_templates_system'
|
||||
);
|
||||
|
||||
await ensureDirectory(templatesDir);
|
||||
console.log(templatesDir)
|
||||
return templatesDir;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {blenderVersion} version
|
||||
* @param {string} template
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function getTemplate(version, template) {
|
||||
try {
|
||||
// Launch the executable
|
||||
const templatesDir = await join(await getTemplatesDir(version),
|
||||
template
|
||||
);
|
||||
return templatesDir;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a specific Blender version.
|
||||
* @param {blenderVersion} version - The version object to launch
|
||||
@ -386,18 +538,34 @@ export async function launchBlenderVersion(version, template = null) {
|
||||
if (!libraryDir) {
|
||||
return {
|
||||
success: false,
|
||||
message: `couldn't find library: ${version.executable}`
|
||||
message: `couldn't find library`
|
||||
};
|
||||
}
|
||||
const blenderConfigPath = await join(libraryDir, BASE_LIBRARY_DIR, 'config', version.version);
|
||||
|
||||
// Launch the executable
|
||||
let bannerPath;
|
||||
if (template) {
|
||||
const templateDir = await getTemplate(version, template);
|
||||
bannerPath = await join(templateDir, 'banner.png');
|
||||
} else {
|
||||
bannerPath = await join(version.path, 'banner.png');
|
||||
}
|
||||
const args = template ? ['--app-template', template] : [];
|
||||
|
||||
/*if (template) {
|
||||
|
||||
} else {
|
||||
bannerPath = await join(version.path, 'banner.png');
|
||||
} */
|
||||
|
||||
console.log('launching', version.executable, args);
|
||||
invoke('launch_binary', {
|
||||
path: version.executable,
|
||||
args: [],
|
||||
args: args,
|
||||
env: {
|
||||
BLENDER_USER_RESOURCES: blenderConfigPath,
|
||||
BLENDER_CUSTOM_SPLASH_BANNER: await join(version.path, 'banner.png')
|
||||
BLENDER_CUSTOM_SPLASH_BANNER: bannerPath
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
@ -405,11 +573,16 @@ export async function launchBlenderVersion(version, template = null) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
return {
|
||||
success: false,
|
||||
message: `Launch failed: ${errorMessage}`
|
||||
message: `. failed: ${errorMessage}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} versionPath
|
||||
* @returns {Promise<string | null>} Path to the Blender executable, or null if not found
|
||||
*/
|
||||
async function findBlenderExecutable(versionPath) {
|
||||
const settings = get(currentSettings);
|
||||
const currentPlatform = settings.defaultPlatform;
|
||||
|
||||
12
src/lib/notification.js
Normal file
@ -0,0 +1,12 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const notification = writable(null);
|
||||
|
||||
/**
|
||||
* Show a notification popup.
|
||||
* @param {string} message - The message to display
|
||||
* @param {number} [timeout=3000] - Auto-dismiss timeout in milliseconds
|
||||
*/
|
||||
export function notify(message, timeout = 3000) {
|
||||
notification.set({ message, timeout });
|
||||
}
|
||||
@ -8,17 +8,17 @@
|
||||
// MODULES
|
||||
import { setupTrayIcon } from '$lib/trayicon';
|
||||
import { getSettings, currentSettings } from '$lib/settings';
|
||||
import { getInstalledVersions, currentInstalledVersions } from '$lib/library';
|
||||
import { getBlenderReleases, blenderReleases } from '$lib/blenderfetch';
|
||||
import { downloadTasksStore } from '$lib/download';
|
||||
|
||||
// COMPONENTS
|
||||
import { getInstalledVersions, installedVersionsStore } from '$lib/library.js';
|
||||
import { downloadTasksStore } from '$lib/download.js';
|
||||
import Library from '$lib/components/Library.svelte';
|
||||
import Download from '$lib/components/Download.svelte';
|
||||
import Settings from '$lib/components/Settings.svelte';
|
||||
import Popup from '$lib/components/Popup.svelte';
|
||||
import Dialog from '$lib/components/Dialog.svelte';
|
||||
import Splash from '$lib/components/Splash.svelte';
|
||||
import { notification } from '$lib/notification.js';
|
||||
|
||||
// states
|
||||
let fadeInSettings = { duration: 100 };
|
||||
@ -28,16 +28,23 @@
|
||||
let installedVersions = $state([]);
|
||||
let downloadTasks = $state([]);
|
||||
let settings = $state();
|
||||
let notificationPopup;
|
||||
let initialized = $state(false);
|
||||
let version = $state('');
|
||||
let loadingState = $state('loading'); // load, update, initialized
|
||||
|
||||
notification.subscribe((n) => {
|
||||
if (n) {
|
||||
notificationPopup?.pop(n.message, n.timeout);
|
||||
}
|
||||
});
|
||||
|
||||
async function initStoresListeners() {
|
||||
currentSettings.subscribe((value) => {
|
||||
settings = value;
|
||||
console.log('Loaded settings:', settings);
|
||||
});
|
||||
currentInstalledVersions.subscribe((value) => {
|
||||
installedVersionsStore.subscribe((value) => {
|
||||
installedVersions = value;
|
||||
console.log('Loaded installed versions:', installedVersions);
|
||||
});
|
||||
@ -69,7 +76,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<Popup content="Are you sure you want to delete this file?" type="confirm" />
|
||||
<Popup bind:this={notificationPopup} />
|
||||
<Dialog />
|
||||
|
||||
<div id="main">
|
||||
@ -216,8 +223,8 @@
|
||||
}
|
||||
.version {
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
right: 2rem;
|
||||
bottom: 2.8rem;
|
||||
right: 3rem;
|
||||
z-index: 2;
|
||||
text-align: right;
|
||||
color: var(--light-accent);
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
// Tauri doesn't have a Node.js server to do proper SSR
|
||||
// so we will use adapter-static to prerender the app (SSG)
|
||||
// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info
|
||||
import adapter from "@sveltejs/adapter-static";
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
},
|
||||
kit: {
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||