From 8bceae2396c267c51fa730029993faa2701cb90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Forment?= Date: Tue, 14 Oct 2025 21:32:35 +0200 Subject: [PATCH] Init --- .gitignore | 24 + .vscode/extensions.json | 3 + README.md | 47 + index.html | 13 + package.json | 36 + pnpm-lock.yaml | 1380 +++++++++++++++++++++ public/vite.svg | 1 + src/App.svelte | 47 + src/app.css | 79 ++ src/assets/svelte.svg | 1 + src/lib/Counter.svelte | 10 + src/lib/project-system/compression.ts | 166 +++ src/lib/project-system/db.ts | 233 ++++ src/lib/project-system/index.ts | 56 + src/lib/project-system/project-manager.ts | 343 +++++ src/lib/project-system/types.ts | 70 ++ src/main.ts | 9 + svelte.config.js | 8 + tsconfig.app.json | 21 + tsconfig.json | 7 + tsconfig.node.json | 26 + vite.config.ts | 7 + 22 files changed, 2587 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 public/vite.svg create mode 100644 src/App.svelte create mode 100644 src/app.css create mode 100644 src/assets/svelte.svg create mode 100644 src/lib/Counter.svelte create mode 100644 src/lib/project-system/compression.ts create mode 100644 src/lib/project-system/db.ts create mode 100644 src/lib/project-system/index.ts create mode 100644 src/lib/project-system/project-manager.ts create mode 100644 src/lib/project-system/types.ts create mode 100644 src/main.ts create mode 100644 svelte.config.js create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6cd94f --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..4c3f06d --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + oldboy + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..ec61ba6 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "oldboy", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tsconfig/svelte": "^5.0.5", + "@types/node": "^24.6.0", + "@types/pako": "^2.0.4", + "svelte": "^5.39.6", + "svelte-check": "^4.3.2", + "typescript": "~5.9.3", + "vite": "npm:rolldown-vite@7.1.14" + }, + "pnpm": { + "overrides": { + "vite": "npm:rolldown-vite@7.1.14" + } + }, + "dependencies": { + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.4", + "@codemirror/theme-one-dark": "^6.1.3", + "@csound/browser": "7.0.0-beta11", + "codemirror": "^6.0.2", + "pako": "^2.1.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..0569d05 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1380 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + vite: npm:rolldown-vite@7.1.14 + +importers: + + .: + dependencies: + '@codemirror/lang-css': + specifier: ^6.3.1 + version: 6.3.1 + '@codemirror/lang-html': + specifier: ^6.4.11 + version: 6.4.11 + '@codemirror/lang-javascript': + specifier: ^6.2.4 + version: 6.2.4 + '@codemirror/theme-one-dark': + specifier: ^6.1.3 + version: 6.1.3 + '@csound/browser': + specifier: 7.0.0-beta11 + version: 7.0.0-beta11 + codemirror: + specifier: ^6.0.2 + version: 6.0.2 + pako: + specifier: ^2.1.0 + version: 2.1.0 + devDependencies: + '@sveltejs/vite-plugin-svelte': + specifier: ^6.2.1 + version: 6.2.1(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13) + '@tsconfig/svelte': + specifier: ^5.0.5 + version: 5.0.5 + '@types/node': + specifier: ^24.6.0 + version: 24.7.2 + '@types/pako': + specifier: ^2.0.4 + version: 2.0.4 + svelte: + specifier: ^5.39.6 + version: 5.39.13 + svelte-check: + specifier: ^4.3.2 + version: 4.3.3(picomatch@4.0.3)(svelte@5.39.13)(typescript@5.9.3) + typescript: + specifier: ~5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.1.14 + version: rolldown-vite@7.1.14(@types/node@24.7.2) + +packages: + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@codemirror/autocomplete@6.19.0': + resolution: {integrity: sha512-61Hfv3cF07XvUxNeC3E7jhG8XNi1Yom1G0lRC936oLnlF+jrbrv8rc/J98XlYzcsAoTVupfsf5fLej1aI8kyIg==} + + '@codemirror/commands@6.9.0': + resolution: {integrity: sha512-454TVgjhO6cMufsyyGN70rGIfJxJEjcqjBG2x2Y03Y/+Fm99d3O/Kv1QDYWuG6hvxsgmjXmBuATikIIYvERX+w==} + + '@codemirror/lang-css@6.3.1': + resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==} + + '@codemirror/lang-html@6.4.11': + resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==} + + '@codemirror/lang-javascript@6.2.4': + resolution: {integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==} + + '@codemirror/language@6.11.3': + resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==} + + '@codemirror/lint@6.9.0': + resolution: {integrity: sha512-wZxW+9XDytH3SKvS8cQzMyQCaaazH8XL1EMHleHe00wVzsv7NBQKVW2yzEHrRhmM7ZOhVdItPbvlRBvMp9ej7A==} + + '@codemirror/search@6.5.11': + resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==} + + '@codemirror/state@6.5.2': + resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==} + + '@codemirror/theme-one-dark@6.1.3': + resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==} + + '@codemirror/view@6.38.6': + resolution: {integrity: sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==} + + '@csound/browser@7.0.0-beta11': + resolution: {integrity: sha512-BGFTMXUdOJA1Xz1ETzbE/y8B/X6dpnrKThiqxDqj45K+ctOWtMqefgH6MojzJjWFwRs8UqhrJmVUq78SbMwGlw==} + + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@lezer/common@1.2.3': + resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} + + '@lezer/css@1.3.0': + resolution: {integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw==} + + '@lezer/highlight@1.2.1': + resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==} + + '@lezer/html@1.3.12': + resolution: {integrity: sha512-RJ7eRWdaJe3bsiiLLHjCFT1JMk8m1YP9kaUbvu2rMLEoOnke9mcTVDyfOslsln0LtujdWespjJ39w6zo+RsQYw==} + + '@lezer/javascript@1.5.4': + resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==} + + '@lezer/lr@1.4.2': + resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==} + + '@marijn/find-cluster-break@1.0.2': + resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + + '@oxc-project/runtime@0.92.0': + resolution: {integrity: sha512-Z7x2dZOmznihvdvCvLKMl+nswtOSVxS2H2ocar+U9xx6iMfTp0VGIrX6a4xB1v80IwOPC7dT1LXIJrY70Xu3Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@oxc-project/types@0.93.0': + resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} + + '@rolldown/binding-android-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + resolution: {integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + resolution: {integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + resolution: {integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + resolution: {integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.41': + resolution: {integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==} + + '@sveltejs/acorn-typescript@1.0.6': + resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1': + resolution: {integrity: sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@sveltejs/vite-plugin-svelte@6.2.1': + resolution: {integrity: sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@tsconfig/svelte@5.0.5': + resolution: {integrity: sha512-48fAnUjKye38FvMiNOj0J9I/4XlQQiZlpe9xaNPfe8vy2Y1hFBt8g1yqf2EGjVvHavo4jf2lC+TQyENCr4BJBQ==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/node@24.7.2': + resolution: {integrity: sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==} + + '@types/pako@2.0.4': + resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + automation-events@7.1.13: + resolution: {integrity: sha512-1Hay5TQPzxsskSqPTH3YXyzE9Iirz82zZDse2vr3+kOR7Sc7om17qIEPsESchlNX0EgKxANwR40i2g/O3GM1Tw==} + engines: {node: '>=18.2.0'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + clone-buffer@1.0.0: + resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} + engines: {node: '>= 0.10'} + + clone-stats@1.0.0: + resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + cloneable-readable@1.1.3: + resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + codemirror@6.0.2: + resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + esrap@2.1.0: + resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + google-closure-compiler-java@20221102.0.1: + resolution: {integrity: sha512-rMKLEma3uSe/6MGHtivDezTv4u5iaDEyxoy9No+1WruPSZ5h1gBZLONcfCA8JaoGojFPdHZI1qbwT0EveEWnAg==} + + google-closure-compiler-linux@20221102.0.1: + resolution: {integrity: sha512-rj1E1whT4j/giidQ44v4RoO8GcvU81VU9YB5RlRM0hWDvCGWjQasDABGnF/YLWLl5PXAAfJpa/hy8ckv5/r97g==} + cpu: [x32, x64] + os: [linux] + + google-closure-compiler-osx@20221102.0.1: + resolution: {integrity: sha512-Cv993yr9a2DLFgYnsv4m6dNUk5jousd6W6la12x2fDbhxTLewYrw7CrCaVEVw1SU3XErVmdHOZQjFsVMhcZjCw==} + cpu: [x32, x64, arm64] + os: [darwin] + + google-closure-compiler-windows@20221102.0.1: + resolution: {integrity: sha512-jRwHGekG/oDihHdKAEiYN5z0cBF+brL0bYtuEOXx4fAmq5tHe4OxKtSEEprCnVZZL0aG/boGprACPvsDRsXT7Q==} + cpu: [x32, x64] + os: [win32] + + google-closure-compiler@20221102.0.1: + resolution: {integrity: sha512-edAlsyJEsy2I983xWBlBfdSme16uyY007HM2OwPOoWPEFgmR100ggUabJbIegXZgbSLH51kyeJMQKuWhiHgzcA==} + engines: {node: '>=10'} + hasBin: true + + google-closure-library@20221102.0.0: + resolution: {integrity: sha512-M5+LWPS99tMB9dOGpZjLT9CdIYpnwBZiwB+dCmZFOOvwJiOWytntzJ/a/hoNF6zxD15l3GWwRJiEkL636D6DRQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + jazz-midi@1.7.9: + resolution: {integrity: sha512-c8c4BBgwxdsIr1iVm53nadCrtH7BUlnX3V95ciK/gbvXN/ndE5+POskBalXgqlc/r9p2XUbdLTrgrC6fou5p9w==} + engines: {node: '>=10.0.0'} + + jzz@1.9.6: + resolution: {integrity: sha512-J7ENLhXwfm2BNDKRUrL8eKtPhUS/CtMBpiafxQHDBcOWSocLhearDKEdh+ylnZFcr5OXWTed0gj6l/txeQA9vg==} + + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + engines: {node: '>= 12.0.0'} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + ramda@0.28.0: + resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + replace-ext@1.0.1: + resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} + engines: {node: '>= 0.10'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rolldown-vite@7.1.14: + resolution: {integrity: sha512-eSiiRJmovt8qDJkGyZuLnbxAOAdie6NCmmd0NkTC0RJI9duiSBTfr8X2mBYJOUFzxQa2USaHmL99J9uMxkjCyw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + esbuild: ^0.25.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + rolldown@1.0.0-beta.41: + resolution: {integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + standardized-audio-context@25.3.77: + resolution: {integrity: sha512-Ki9zNz6pKcC5Pi+QPjPyVsD9GwJIJWgryji0XL9cAJXMGyn+dPOf6Qik1AHei0+UNVcc4BOCa0hWLBzlwqsW/A==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + style-mod@4.1.2: + resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + svelte-check@4.3.3: + resolution: {integrity: sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte@5.39.13: + resolution: {integrity: sha512-NRAAL96UXKwOTgS+8T6tQT8mILlylTJePvUjyUAU+ryE+MQTA71PXiQz5cMsFey2eSttBy+3kt+BR0l1XFNNBw==} + engines: {node: '>=18'} + + text-encoding-shim@1.0.5: + resolution: {integrity: sha512-H7yYW+jRn4yhu60ygZ2f/eMhXPITRt4QSUTKzLm+eCaDsdX8avmgWpmtmHAzesjBVUTAypz9odu5RKUjX5HNYA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.14.0: + resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} + + unmute-ios-audio@3.3.0: + resolution: {integrity: sha512-MmoCOrsS2gn3wLT2tT+hF56Q4V4kksIKn2LHrwAtX6umzQwQHDWSh1slMzH+0WuxTZ62s3w8/wsfIII1FQ7ACg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vinyl-sourcemaps-apply@0.2.1: + resolution: {integrity: sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==} + + vinyl@2.2.1: + resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} + engines: {node: '>= 0.10'} + + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + web-midi-api@2.4.0: + resolution: {integrity: sha512-tTfLdxa5LpOP1NgWByV458iYKgSLhlsIwqCpfbcJuyjProNtuf5UnX97K4JNyuQCqkR+6thQAIsk2BOMSrKaCA==} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + +snapshots: + + '@babel/runtime@7.28.4': {} + + '@codemirror/autocomplete@6.19.0': + dependencies: + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.2.3 + + '@codemirror/commands@6.9.0': + dependencies: + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.2.3 + + '@codemirror/lang-css@6.3.1': + dependencies: + '@codemirror/autocomplete': 6.19.0 + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@lezer/common': 1.2.3 + '@lezer/css': 1.3.0 + + '@codemirror/lang-html@6.4.11': + dependencies: + '@codemirror/autocomplete': 6.19.0 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-javascript': 6.2.4 + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.2.3 + '@lezer/css': 1.3.0 + '@lezer/html': 1.3.12 + + '@codemirror/lang-javascript@6.2.4': + dependencies: + '@codemirror/autocomplete': 6.19.0 + '@codemirror/language': 6.11.3 + '@codemirror/lint': 6.9.0 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.2.3 + '@lezer/javascript': 1.5.4 + + '@codemirror/language@6.11.3': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.2.3 + '@lezer/highlight': 1.2.1 + '@lezer/lr': 1.4.2 + style-mod: 4.1.2 + + '@codemirror/lint@6.9.0': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + crelt: 1.0.6 + + '@codemirror/search@6.5.11': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + crelt: 1.0.6 + + '@codemirror/state@6.5.2': + dependencies: + '@marijn/find-cluster-break': 1.0.2 + + '@codemirror/theme-one-dark@6.1.3': + dependencies: + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/highlight': 1.2.1 + + '@codemirror/view@6.38.6': + dependencies: + '@codemirror/state': 6.5.2 + crelt: 1.0.6 + style-mod: 4.1.2 + w3c-keyname: 2.2.8 + + '@csound/browser@7.0.0-beta11': + dependencies: + eventemitter3: 4.0.7 + google-closure-compiler: 20221102.0.1 + google-closure-library: 20221102.0.0 + pako: 2.1.0 + ramda: 0.28.0 + rimraf: 3.0.2 + standardized-audio-context: 25.3.77 + text-encoding-shim: 1.0.5 + unmute-ios-audio: 3.3.0 + web-midi-api: 2.4.0 + + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@lezer/common@1.2.3': {} + + '@lezer/css@1.3.0': + dependencies: + '@lezer/common': 1.2.3 + '@lezer/highlight': 1.2.1 + '@lezer/lr': 1.4.2 + + '@lezer/highlight@1.2.1': + dependencies: + '@lezer/common': 1.2.3 + + '@lezer/html@1.3.12': + dependencies: + '@lezer/common': 1.2.3 + '@lezer/highlight': 1.2.1 + '@lezer/lr': 1.4.2 + + '@lezer/javascript@1.5.4': + dependencies: + '@lezer/common': 1.2.3 + '@lezer/highlight': 1.2.1 + '@lezer/lr': 1.4.2 + + '@lezer/lr@1.4.2': + dependencies: + '@lezer/common': 1.2.3 + + '@marijn/find-cluster-break@1.0.2': {} + + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@oxc-project/runtime@0.92.0': {} + + '@oxc-project/types@0.93.0': {} + + '@rolldown/binding-android-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.41': {} + + '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13))(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13)': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.1(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13) + debug: 4.4.3 + svelte: 5.39.13 + vite: rolldown-vite@7.1.14(@types/node@24.7.2) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@6.2.1(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13)': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13))(rolldown-vite@7.1.14(@types/node@24.7.2))(svelte@5.39.13) + debug: 4.4.3 + deepmerge: 4.3.1 + magic-string: 0.30.19 + svelte: 5.39.13 + vite: rolldown-vite@7.1.14(@types/node@24.7.2) + vitefu: 1.1.1(rolldown-vite@7.1.14(@types/node@24.7.2)) + transitivePeerDependencies: + - supports-color + + '@tsconfig/svelte@5.0.5': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.8': {} + + '@types/node@24.7.2': + dependencies: + undici-types: 7.14.0 + + '@types/pako@2.0.4': {} + + acorn@8.15.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansis@4.2.0: {} + + aria-query@5.3.2: {} + + automation-events@7.1.13: + dependencies: + '@babel/runtime': 7.28.4 + tslib: 2.8.1 + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + clone-buffer@1.0.0: {} + + clone-stats@1.0.0: {} + + clone@2.1.2: {} + + cloneable-readable@1.1.3: + dependencies: + inherits: 2.0.4 + process-nextick-args: 2.0.1 + readable-stream: 2.3.8 + + clsx@2.1.1: {} + + codemirror@6.0.2: + dependencies: + '@codemirror/autocomplete': 6.19.0 + '@codemirror/commands': 6.9.0 + '@codemirror/language': 6.11.3 + '@codemirror/lint': 6.9.0 + '@codemirror/search': 6.5.11 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + core-util-is@1.0.3: {} + + crelt@1.0.6: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deepmerge@4.3.1: {} + + detect-libc@2.1.2: {} + + esm-env@1.2.2: {} + + esrap@2.1.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + eventemitter3@4.0.7: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + google-closure-compiler-java@20221102.0.1: {} + + google-closure-compiler-linux@20221102.0.1: + optional: true + + google-closure-compiler-osx@20221102.0.1: + optional: true + + google-closure-compiler-windows@20221102.0.1: + optional: true + + google-closure-compiler@20221102.0.1: + dependencies: + chalk: 4.1.2 + google-closure-compiler-java: 20221102.0.1 + minimist: 1.2.8 + vinyl: 2.2.1 + vinyl-sourcemaps-apply: 0.2.1 + optionalDependencies: + google-closure-compiler-linux: 20221102.0.1 + google-closure-compiler-osx: 20221102.0.1 + google-closure-compiler-windows: 20221102.0.1 + + google-closure-library@20221102.0.0: {} + + has-flag@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + isarray@1.0.0: {} + + jazz-midi@1.7.9: {} + + jzz@1.9.6: + dependencies: + jazz-midi: 1.7.9 + + lightningcss-android-arm64@1.30.2: + optional: true + + lightningcss-darwin-arm64@1.30.2: + optional: true + + lightningcss-darwin-x64@1.30.2: + optional: true + + lightningcss-freebsd-x64@1.30.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.2: + optional: true + + lightningcss-linux-arm64-gnu@1.30.2: + optional: true + + lightningcss-linux-arm64-musl@1.30.2: + optional: true + + lightningcss-linux-x64-gnu@1.30.2: + optional: true + + lightningcss-linux-x64-musl@1.30.2: + optional: true + + lightningcss-win32-arm64-msvc@1.30.2: + optional: true + + lightningcss-win32-x64-msvc@1.30.2: + optional: true + + lightningcss@1.30.2: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 + + locate-character@3.0.0: {} + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mri@1.2.0: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + pako@2.1.0: {} + + path-is-absolute@1.0.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + process-nextick-args@2.0.1: {} + + ramda@0.28.0: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + remove-trailing-separator@1.1.0: {} + + replace-ext@1.0.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rolldown-vite@7.1.14(@types/node@24.7.2): + dependencies: + '@oxc-project/runtime': 0.92.0 + fdir: 6.5.0(picomatch@4.0.3) + lightningcss: 1.30.2 + picomatch: 4.0.3 + postcss: 8.5.6 + rolldown: 1.0.0-beta.41 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.7.2 + fsevents: 2.3.3 + + rolldown@1.0.0-beta.41: + dependencies: + '@oxc-project/types': 0.93.0 + '@rolldown/pluginutils': 1.0.0-beta.41 + ansis: 4.2.0 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-x64': 1.0.0-beta.41 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.41 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.41 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.41 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.41 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.41 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-buffer@5.1.2: {} + + source-map-js@1.2.1: {} + + source-map@0.5.7: {} + + standardized-audio-context@25.3.77: + dependencies: + '@babel/runtime': 7.28.4 + automation-events: 7.1.13 + tslib: 2.8.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + style-mod@4.1.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + svelte-check@4.3.3(picomatch@4.0.3)(svelte@5.39.13)(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.3) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.39.13 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte@5.39.13: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + esm-env: 1.2.2 + esrap: 2.1.0 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.19 + zimmerframe: 1.1.4 + + text-encoding-shim@1.0.5: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tslib@2.8.1: {} + + typescript@5.9.3: {} + + undici-types@7.14.0: {} + + unmute-ios-audio@3.3.0: {} + + util-deprecate@1.0.2: {} + + vinyl-sourcemaps-apply@0.2.1: + dependencies: + source-map: 0.5.7 + + vinyl@2.2.1: + dependencies: + clone: 2.1.2 + clone-buffer: 1.0.0 + clone-stats: 1.0.0 + cloneable-readable: 1.1.3 + remove-trailing-separator: 1.1.0 + replace-ext: 1.0.1 + + vitefu@1.1.1(rolldown-vite@7.1.14(@types/node@24.7.2)): + optionalDependencies: + vite: rolldown-vite@7.1.14(@types/node@24.7.2) + + w3c-keyname@2.2.8: {} + + web-midi-api@2.4.0: + dependencies: + jzz: 1.9.6 + + wrappy@1.0.2: {} + + zimmerframe@1.1.4: {} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte new file mode 100644 index 0000000..f75b68a --- /dev/null +++ b/src/App.svelte @@ -0,0 +1,47 @@ + + +
+
+ + + + + + +
+

Vite + Svelte

+ +
+ +
+ +

+ Check out SvelteKit, the official Svelte app framework powered by Vite! +

+ +

+ Click on the Vite and Svelte logos to learn more +

+
+ + diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..61ba367 --- /dev/null +++ b/src/app.css @@ -0,0 +1,79 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/src/assets/svelte.svg b/src/assets/svelte.svg new file mode 100644 index 0000000..c5e0848 --- /dev/null +++ b/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/lib/Counter.svelte b/src/lib/Counter.svelte new file mode 100644 index 0000000..37d75ce --- /dev/null +++ b/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/lib/project-system/compression.ts b/src/lib/project-system/compression.ts new file mode 100644 index 0000000..57aa4fe --- /dev/null +++ b/src/lib/project-system/compression.ts @@ -0,0 +1,166 @@ +import pako from 'pako'; +import type { CsoundProject, CompressedProject } from './types'; + +const COMPRESSION_VERSION = 1; + +/** + * Convert a string to a Uint8Array + */ +function stringToUint8Array(str: string): Uint8Array { + const encoder = new TextEncoder(); + return encoder.encode(str); +} + +/** + * Convert a Uint8Array to a string + */ +function uint8ArrayToString(arr: Uint8Array): string { + const decoder = new TextDecoder(); + return decoder.decode(arr); +} + +/** + * Convert Uint8Array to base64 string (URL-safe) + */ +function uint8ArrayToBase64(arr: Uint8Array): string { + let binary = ''; + const len = arr.byteLength; + for (let i = 0; i < len; i++) { + binary += String.fromCharCode(arr[i]); + } + return btoa(binary) + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=/g, ''); +} + +/** + * Convert base64 string (URL-safe) to Uint8Array + */ +function base64ToUint8Array(base64: string): Uint8Array { + // Restore standard base64 + const standardBase64 = base64 + .replace(/-/g, '+') + .replace(/_/g, '/'); + + // Add padding if needed + const padding = '='.repeat((4 - (standardBase64.length % 4)) % 4); + const paddedBase64 = standardBase64 + padding; + + const binary = atob(paddedBase64); + const len = binary.length; + const arr = new Uint8Array(len); + + for (let i = 0; i < len; i++) { + arr[i] = binary.charCodeAt(i); + } + + return arr; +} + +/** + * Compress a project to a base64 string for sharing + */ +export function compressProject(project: CsoundProject): CompressedProject { + try { + // Convert project to JSON string + const jsonString = JSON.stringify(project); + + // Convert to Uint8Array + const uint8Array = stringToUint8Array(jsonString); + + // Compress using pako (gzip) + const compressed = pako.deflate(uint8Array, { level: 9 }); + + // Convert to base64 + const base64 = uint8ArrayToBase64(compressed); + + return { + data: base64, + version: COMPRESSION_VERSION, + }; + } catch (error) { + throw new Error(`Failed to compress project: ${error instanceof Error ? error.message : 'Unknown error'}`); + } +} + +/** + * Decompress a base64 string back to a project + */ +export function decompressProject(compressed: CompressedProject): CsoundProject { + try { + // Check version compatibility + if (compressed.version !== COMPRESSION_VERSION) { + throw new Error(`Unsupported compression version: ${compressed.version}`); + } + + // Convert base64 to Uint8Array + const uint8Array = base64ToUint8Array(compressed.data); + + // Decompress using pako + const decompressed = pako.inflate(uint8Array); + + // Convert to string + const jsonString = uint8ArrayToString(decompressed); + + // Parse JSON + const project = JSON.parse(jsonString) as CsoundProject; + + // Validate that we have the required fields + if (!project.id || !project.title || !project.content === undefined) { + throw new Error('Invalid project data structure'); + } + + return project; + } catch (error) { + throw new Error(`Failed to decompress project: ${error instanceof Error ? error.message : 'Unknown error'}`); + } +} + +/** + * Create a shareable URL from a project + */ +export function projectToShareUrl(project: CsoundProject, baseUrl: string = window.location.origin): string { + const compressed = compressProject(project); + const params = new URLSearchParams({ + v: compressed.version.toString(), + d: compressed.data, + }); + + return `${baseUrl}?${params.toString()}`; +} + +/** + * Extract a project from a URL + */ +export function projectFromShareUrl(url: string): CsoundProject { + try { + const urlObj = new URL(url); + const params = urlObj.searchParams; + + const version = parseInt(params.get('v') || '1', 10); + const data = params.get('d'); + + if (!data) { + throw new Error('No project data found in URL'); + } + + const compressed: CompressedProject = { version, data }; + return decompressProject(compressed); + } catch (error) { + throw new Error(`Failed to parse project from URL: ${error instanceof Error ? error.message : 'Unknown error'}`); + } +} + +/** + * Calculate the approximate compression ratio + */ +export function getCompressionRatio(project: CsoundProject): number { + const original = JSON.stringify(project); + const compressed = compressProject(project); + + const originalSize = new TextEncoder().encode(original).length; + const compressedSize = base64ToUint8Array(compressed.data).length; + + return originalSize / compressedSize; +} diff --git a/src/lib/project-system/db.ts b/src/lib/project-system/db.ts new file mode 100644 index 0000000..93348a9 --- /dev/null +++ b/src/lib/project-system/db.ts @@ -0,0 +1,233 @@ +import type { CsoundProject } from './types'; + +const DB_NAME = 'csound-projects-db'; +const DB_VERSION = 1; +const STORE_NAME = 'projects'; + +/** + * Database wrapper for IndexedDB operations + */ +class ProjectDatabase { + private db: IDBDatabase | null = null; + private initPromise: Promise | null = null; + + /** + * Initialize the database connection + */ + async init(): Promise { + if (this.db) { + return; + } + + if (this.initPromise) { + return this.initPromise; + } + + this.initPromise = new Promise((resolve, reject) => { + const request = indexedDB.open(DB_NAME, DB_VERSION); + + request.onerror = () => { + reject(new Error(`Failed to open database: ${request.error?.message}`)); + }; + + request.onsuccess = () => { + this.db = request.result; + resolve(); + }; + + request.onupgradeneeded = (event) => { + const db = (event.target as IDBOpenDBRequest).result; + + // Create object store if it doesn't exist + if (!db.objectStoreNames.contains(STORE_NAME)) { + const objectStore = db.createObjectStore(STORE_NAME, { + keyPath: 'id', + }); + + // Create indexes for efficient querying + objectStore.createIndex('title', 'title', { unique: false }); + objectStore.createIndex('author', 'author', { unique: false }); + objectStore.createIndex('dateCreated', 'dateCreated', { unique: false }); + objectStore.createIndex('dateModified', 'dateModified', { unique: false }); + objectStore.createIndex('tags', 'tags', { unique: false, multiEntry: true }); + } + }; + }); + + return this.initPromise; + } + + /** + * Ensure database is initialized + */ + private async ensureDb(): Promise { + await this.init(); + if (!this.db) { + throw new Error('Database not initialized'); + } + return this.db; + } + + /** + * Get a project by ID + */ + async get(id: string): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.get(id); + + request.onsuccess = () => { + resolve(request.result || null); + }; + + request.onerror = () => { + reject(new Error(`Failed to get project: ${request.error?.message}`)); + }; + }); + } + + /** + * Get all projects + */ + async getAll(): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.getAll(); + + request.onsuccess = () => { + resolve(request.result || []); + }; + + request.onerror = () => { + reject(new Error(`Failed to get all projects: ${request.error?.message}`)); + }; + }); + } + + /** + * Save or update a project + */ + async put(project: CsoundProject): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + const request = store.put(project); + + request.onsuccess = () => { + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to save project: ${request.error?.message}`)); + }; + }); + } + + /** + * Delete a project by ID + */ + async delete(id: string): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + const request = store.delete(id); + + request.onsuccess = () => { + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to delete project: ${request.error?.message}`)); + }; + }); + } + + /** + * Search projects by tag + */ + async getByTag(tag: string): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const index = store.index('tags'); + const request = index.getAll(tag); + + request.onsuccess = () => { + resolve(request.result || []); + }; + + request.onerror = () => { + reject(new Error(`Failed to get projects by tag: ${request.error?.message}`)); + }; + }); + } + + /** + * Search projects by author + */ + async getByAuthor(author: string): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const index = store.index('author'); + const request = index.getAll(author); + + request.onsuccess = () => { + resolve(request.result || []); + }; + + request.onerror = () => { + reject(new Error(`Failed to get projects by author: ${request.error?.message}`)); + }; + }); + } + + /** + * Clear all projects (use with caution!) + */ + async clear(): Promise { + const db = await this.ensureDb(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction([STORE_NAME], 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + const request = store.clear(); + + request.onsuccess = () => { + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to clear projects: ${request.error?.message}`)); + }; + }); + } + + /** + * Close the database connection + */ + close(): void { + if (this.db) { + this.db.close(); + this.db = null; + this.initPromise = null; + } + } +} + +// Export singleton instance +export const projectDb = new ProjectDatabase(); diff --git a/src/lib/project-system/index.ts b/src/lib/project-system/index.ts new file mode 100644 index 0000000..fe09586 --- /dev/null +++ b/src/lib/project-system/index.ts @@ -0,0 +1,56 @@ +/** + * Csound Project Management System + * + * This module provides a complete project system for managing Csound code files + * with browser-based storage (IndexedDB) and import/export functionality via + * compressed URLs. + * + * @example + * ```typescript + * import { projectManager } from './lib/project-system'; + * + * // Initialize + * await projectManager.init(); + * + * // Create a new project + * const result = await projectManager.createProject({ + * title: 'My First Csound Project', + * author: 'John Doe', + * content: '...', + * tags: ['synth', 'experiment'] + * }); + * + * // Get all projects + * const projects = await projectManager.getAllProjects(); + * + * // Export to shareable URL + * const urlResult = await projectManager.exportProjectToUrl(result.data.id); + * + * // Import from URL + * const imported = await projectManager.importProjectFromUrl(url); + * ``` + */ + +// Export types +export type { + CsoundProject, + CreateProjectData, + UpdateProjectData, + CompressedProject, + Result, +} from './types'; + +// Export main API +export { ProjectManager, projectManager } from './project-manager'; + +// Export database (for advanced usage) +export { projectDb } from './db'; + +// Export compression utilities (for advanced usage) +export { + compressProject, + decompressProject, + projectToShareUrl, + projectFromShareUrl, + getCompressionRatio, +} from './compression'; diff --git a/src/lib/project-system/project-manager.ts b/src/lib/project-system/project-manager.ts new file mode 100644 index 0000000..97436f2 --- /dev/null +++ b/src/lib/project-system/project-manager.ts @@ -0,0 +1,343 @@ +import type { CsoundProject, CreateProjectData, UpdateProjectData, Result } from './types'; +import { projectDb } from './db'; +import { compressProject, decompressProject, projectToShareUrl, projectFromShareUrl } from './compression'; + +const CSOUND_VERSION = '7.0.0'; // This should be detected from @csound/browser + +/** + * Generate a unique ID for a project + */ +function generateId(): string { + return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; +} + +/** + * Get the current ISO timestamp + */ +function getCurrentTimestamp(): string { + return new Date().toISOString(); +} + +/** + * Project Manager - Main API for managing Csound projects + */ +export class ProjectManager { + /** + * Initialize the project manager (initializes database) + */ + async init(): Promise { + await projectDb.init(); + } + + /** + * Create a new project + */ + async createProject(data: CreateProjectData): Promise> { + try { + const now = getCurrentTimestamp(); + + const project: CsoundProject = { + id: generateId(), + title: data.title, + author: data.author, + dateCreated: now, + dateModified: now, + saveCount: 0, + content: data.content || '', + tags: data.tags || [], + csoundVersion: CSOUND_VERSION, + }; + + await projectDb.put(project); + + return { success: true, data: project }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to create project'), + }; + } + } + + /** + * Get a project by ID + */ + async getProject(id: string): Promise> { + try { + const project = await projectDb.get(id); + + if (!project) { + return { + success: false, + error: new Error(`Project not found: ${id}`), + }; + } + + return { success: true, data: project }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to get project'), + }; + } + } + + /** + * Get all projects + */ + async getAllProjects(): Promise> { + try { + const projects = await projectDb.getAll(); + return { success: true, data: projects }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to get projects'), + }; + } + } + + /** + * Update an existing project + */ + async updateProject(data: UpdateProjectData): Promise> { + try { + const existingProject = await projectDb.get(data.id); + + if (!existingProject) { + return { + success: false, + error: new Error(`Project not found: ${data.id}`), + }; + } + + const updatedProject: CsoundProject = { + ...existingProject, + ...(data.title !== undefined && { title: data.title }), + ...(data.author !== undefined && { author: data.author }), + ...(data.content !== undefined && { content: data.content }), + ...(data.tags !== undefined && { tags: data.tags }), + dateModified: getCurrentTimestamp(), + saveCount: existingProject.saveCount + 1, + }; + + await projectDb.put(updatedProject); + + return { success: true, data: updatedProject }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to update project'), + }; + } + } + + /** + * Delete a project + */ + async deleteProject(id: string): Promise> { + try { + await projectDb.delete(id); + return { success: true, data: undefined }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to delete project'), + }; + } + } + + /** + * Search projects by tag + */ + async getProjectsByTag(tag: string): Promise> { + try { + const projects = await projectDb.getByTag(tag); + return { success: true, data: projects }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to search projects by tag'), + }; + } + } + + /** + * Search projects by author + */ + async getProjectsByAuthor(author: string): Promise> { + try { + const projects = await projectDb.getByAuthor(author); + return { success: true, data: projects }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to search projects by author'), + }; + } + } + + /** + * Export a project to a shareable URL + */ + async exportProjectToUrl(id: string, baseUrl?: string): Promise> { + try { + const project = await projectDb.get(id); + + if (!project) { + return { + success: false, + error: new Error(`Project not found: ${id}`), + }; + } + + const url = projectToShareUrl(project, baseUrl); + + return { success: true, data: url }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to export project'), + }; + } + } + + /** + * Export a project to compressed data (for copying to clipboard, etc.) + */ + async exportProjectToCompressed(id: string): Promise> { + try { + const project = await projectDb.get(id); + + if (!project) { + return { + success: false, + error: new Error(`Project not found: ${id}`), + }; + } + + const compressed = compressProject(project); + + return { success: true, data: compressed.data }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to export project'), + }; + } + } + + /** + * Import a project from a URL + */ + async importProjectFromUrl(url: string): Promise> { + try { + const project = projectFromShareUrl(url); + + // Generate a new ID and reset timestamps + const now = getCurrentTimestamp(); + const importedProject: CsoundProject = { + ...project, + id: generateId(), + dateCreated: now, + dateModified: now, + saveCount: 0, + title: `${project.title} (imported)`, + }; + + await projectDb.put(importedProject); + + return { success: true, data: importedProject }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to import project'), + }; + } + } + + /** + * Import a project from compressed data + */ + async importProjectFromCompressed(compressedData: string): Promise> { + try { + const project = decompressProject({ + data: compressedData, + version: 1, + }); + + // Generate a new ID and reset timestamps + const now = getCurrentTimestamp(); + const importedProject: CsoundProject = { + ...project, + id: generateId(), + dateCreated: now, + dateModified: now, + saveCount: 0, + title: `${project.title} (imported)`, + }; + + await projectDb.put(importedProject); + + return { success: true, data: importedProject }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to import project'), + }; + } + } + + /** + * Duplicate a project + */ + async duplicateProject(id: string): Promise> { + try { + const originalProject = await projectDb.get(id); + + if (!originalProject) { + return { + success: false, + error: new Error(`Project not found: ${id}`), + }; + } + + const now = getCurrentTimestamp(); + const duplicatedProject: CsoundProject = { + ...originalProject, + id: generateId(), + title: `${originalProject.title} (copy)`, + dateCreated: now, + dateModified: now, + saveCount: 0, + }; + + await projectDb.put(duplicatedProject); + + return { success: true, data: duplicatedProject }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to duplicate project'), + }; + } + } + + /** + * Clear all projects (use with caution!) + */ + async clearAllProjects(): Promise> { + try { + await projectDb.clear(); + return { success: true, data: undefined }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error : new Error('Failed to clear projects'), + }; + } + } +} + +// Export singleton instance +export const projectManager = new ProjectManager(); diff --git a/src/lib/project-system/types.ts b/src/lib/project-system/types.ts new file mode 100644 index 0000000..35e931e --- /dev/null +++ b/src/lib/project-system/types.ts @@ -0,0 +1,70 @@ +/** + * Core data structure for a Csound project + */ +export interface CsoundProject { + /** Unique identifier for the project */ + id: string; + + /** User-defined project title */ + title: string; + + /** Project author name */ + author: string; + + /** Date when the project was created (ISO string) */ + dateCreated: string; + + /** Date when the project was last modified (ISO string) */ + dateModified: string; + + /** Number of times the project has been saved */ + saveCount: number; + + /** The Csound code content */ + content: string; + + /** Optional tags for categorization */ + tags: string[]; + + /** Csound version used to create this project */ + csoundVersion: string; +} + +/** + * Data structure for creating a new project (omits auto-generated fields) + */ +export interface CreateProjectData { + title: string; + author: string; + content?: string; + tags?: string[]; +} + +/** + * Data structure for updating an existing project + */ +export interface UpdateProjectData { + id: string; + title?: string; + author?: string; + content?: string; + tags?: string[]; +} + +/** + * Compressed project data for import/export via links + */ +export interface CompressedProject { + /** Base64-encoded compressed project data */ + data: string; + + /** Version of the compression format (for future compatibility) */ + version: number; +} + +/** + * Result type for async operations + */ +export type Result = + | { success: true; data: T } + | { success: false; error: E }; diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..664a057 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,9 @@ +import { mount } from 'svelte' +import './app.css' +import App from './App.svelte' + +const app = mount(App, { + target: document.getElementById('app')!, +}) + +export default app diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..96b3455 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,8 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */ +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..31c18cf --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "module": "ESNext", + "types": ["svelte", "vite/client"], + "noEmit": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "moduleDetection": "force" + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..8a67f62 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..d32eba1 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [svelte()], +})