diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index bdeee8b..c57d434 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,26 +1,28 @@ # Unbroken - Tactical Barbell Tracker -Unbroken is a Svelte 5 + TypeScript Progressive Web App (PWA) built with Vite for tracking Tactical Barbell workouts. It features workout tracking, rest timers, exercise database, and training block templates. The app is deployed on Cloudflare Pages. +Unbroken is a SvelteKit + TypeScript Progressive Web App (PWA) for tracking Tactical Barbell workouts. It features a comprehensive REST API, server-side rendering, workout tracking, rest timers, exercise database, and training block templates. The app is deployed on Cloudflare Pages with Cloudflare Workers. Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. ## Working Effectively ### Bootstrap, Build, and Test -- Install dependencies: `npm install` -- takes 45 seconds. NEVER CANCEL. Set timeout to 60+ seconds. +- Install dependencies: `npm install` -- takes 20-25 seconds. NEVER CANCEL. Set timeout to 60+ seconds. - Run linting: `npm run lint` -- takes 1.5 seconds. Set timeout to 30+ seconds. -- Run type checking: `npm run type-check` -- takes 2 seconds. Set timeout to 30+ seconds. -- Build for production: `npm run build` -- takes 6.5 seconds. NEVER CANCEL. Set timeout to 30+ seconds. +- Run type checking: `npm run type-check` -- takes 3-4 seconds (includes SvelteKit sync). Set timeout to 30+ seconds. +- Build for production: `npm run build` -- takes 15-20 seconds (includes SSR bundle). NEVER CANCEL. Set timeout to 60+ seconds. - Fix linting issues: `npm run lint:fix` -- takes 1.5 seconds. Set timeout to 30+ seconds. +- Sync SvelteKit files: `npm run sync` -- takes 1 second. Set timeout to 30+ seconds. ### Run the Application - ALWAYS run `npm install` first if working with a fresh clone. -- Development server: `npm run dev` -- starts in <1 second, serves on http://localhost:5173 +- Development server: `npm run dev` -- starts in 1-2 seconds, serves on http://localhost:5173 - Preview production build: `npm run preview` -- serves production build on http://localhost:4173 +- Sync SvelteKit generated files: `npm run sync` -- regenerates types and routes ### Validation - ALWAYS manually validate any new code by testing complete workout scenarios. -- Test the primary workout flow: Start app → Click "Start Today's Workout" → Complete at least one set → Verify rest timer appears → Test weight adjustments. +- Test the primary workout flow: Start app → Navigate to "Workout" tab → Click "Start Today's Workout" → Complete at least one set → Verify rest timer appears → Test weight adjustments. - ALWAYS test at least one complete end-to-end workout scenario after making changes. - Test on development server (npm run dev) for iterative changes. - Always run `npm run lint && npm run type-check && npm run build` before you are done or the CI (.github/workflows/ci.yml) will fail. @@ -32,6 +34,7 @@ After making changes, always test these key scenarios: 1. **Workout Flow Validation**: - Start development server: `npm run dev` - Access http://localhost:5173 + - Navigate to "Workout" tab using tab navigation - Click "Start Today's Workout" button - Complete at least one exercise set by clicking the checkmark button - Verify rest timer appears and counts down properly @@ -40,12 +43,13 @@ After making changes, always test these key scenarios: 2. **Navigation Validation**: - Test all tab navigation (overview, workout, history, settings) - - Verify training block information displays correctly - - Check that current block and upcoming blocks show properly + - Verify SvelteKit routing works correctly between pages + - Check that training block information displays correctly on overview + - Verify API endpoints respond correctly (check browser network tab) 3. **Build Pipeline Validation**: - - Ensure `npm run build` completes successfully - - Verify dist/ directory is created with proper assets + - Ensure `npm run build` completes successfully with SSR bundle + - Verify `.svelte-kit/output/` directory is created with proper client and server assets - Test production preview with `npm run preview` ## Common Tasks @@ -54,43 +58,59 @@ After making changes, always test these key scenarios: ``` . ├── .github/ # GitHub Actions workflows (CI/CD) -├── .eslintrc.cjs # ESLint configuration -├── dist/ # Build output (generated by npm run build) -├── index.html # HTML template with PWA meta tags -├── package.json # Dependencies and scripts -├── postcss.config.js # PostCSS configuration for Tailwind -├── public/ # Static assets (icons, favicons) -├── src/ # Source code -│ ├── App.svelte # Main application component -│ ├── blockTemplates.ts # Training block templates and configurations -│ ├── components/ # Svelte components (StrengthWorkouts, CardioWorkouts, etc.) -│ ├── app.css # Global styles with Tailwind CSS -│ ├── main.ts # Entry point -│ ├── storage.ts # LocalStorage utilities -│ ├── types.ts # TypeScript type definitions -│ └── utils.ts # Shared utility functions (weight calculations, notifications) -├── tailwind.config.js # Tailwind CSS configuration -├── tsconfig.json # TypeScript configuration -├── vite.config.ts # Vite configuration with PWA plugin -├── svelte.config.js # Svelte configuration -└── wrangler.jsonc # Cloudflare Pages configuration +├── eslint.config.js # ESLint v9 flat configuration +├── .svelte-kit/ # SvelteKit generated files (git ignored) +├── static/ # Static assets (icons, favicons) +├── src/ # Source code +│ ├── routes/ # SvelteKit file-based routing +│ │ ├── +layout.svelte # Main layout with navigation and tab system +│ │ ├── +layout.ts # Layout data loading +│ │ ├── +page.svelte # Overview page (home/dashboard) +│ │ ├── api/ # REST API endpoints +│ │ │ ├── exercises/ # Exercise management (1RM, 10RM, current block) +│ │ │ ├── training-blocks/ # Training block templates and management +│ │ │ ├── training-plan/ # Training plan drag & drop management +│ │ │ ├── workout/ # Workout state, current, completion +│ │ │ └── history/ # Workout history endpoints +│ │ ├── workout/ # Workout page route +│ │ │ ├── +page.svelte # Strength/cardio workout interface with rest timer +│ │ │ └── +page.ts # Workout page data loading +│ │ ├── history/ # History page route +│ │ │ └── +page.svelte # Workout history display +│ │ └── settings/ # Settings page route +│ │ └── +page.svelte # Exercise database and training plan management +│ ├── lib/ # Shared library code (SvelteKit convention) +│ │ ├── blockTemplates.ts # Training block templates and configurations +│ │ ├── stores.ts # Client-side reactive stores for app state +│ │ ├── types.ts # Centralized TypeScript interfaces and types +│ │ └── utils.ts # Shared utility functions (weight calculations, notifications) +│ ├── app.html # HTML template with PWA meta tags +│ ├── app.d.ts # SvelteKit app type definitions +│ └── app.css # Global styles with Tailwind CSS +├── tailwind.config.js # Tailwind CSS configuration +├── tsconfig.json # TypeScript configuration +├── vite.config.ts # Vite configuration with SvelteKit and PWA plugin +├── svelte.config.js # Svelte and SvelteKit configuration with Cloudflare adapter +└── wrangler.jsonc # Cloudflare Pages configuration ``` ### Key Components and Files -- `src/blockTemplates.ts` - Core training block configurations (endurance, powerbuilding, strength blocks) -- `src/components/StrengthWorkouts.svelte` - Main workout interface with rest timers and set tracking -- `src/types.ts` - All TypeScript interfaces and types for workouts, exercises, and app state -- `src/utils.ts` - Weight calculations, notifications, and utility functions -- `src/storage.ts` - LocalStorage persistence for app state and workout history +- `src/lib/blockTemplates.ts` - Core training block configurations (endurance, powerbuilding, strength blocks) +- `src/routes/workout/+page.svelte` - Main workout interface with rest timers and set tracking +- `src/routes/api/` - REST API endpoints for all data operations +- `src/lib/types.ts` - All TypeScript interfaces and types for workouts, exercises, and app state +- `src/lib/utils.ts` - Weight calculations, notifications, and utility functions +- `src/lib/stores.ts` - Client-side reactive stores for app state management ### Framework and Technology Stack +- **SvelteKit** - Full-stack web framework with file-based routing and server-side rendering - **Svelte 5** with TypeScript and runes for reactive state management - **Vite** for build tooling and development server - **Tailwind CSS** for styling (utility-first CSS framework) - **PWA** capabilities via vite-plugin-pwa - **Lucide Svelte** for icons -- **ESLint** for code quality with Svelte plugin -- **Cloudflare Pages** for deployment +- **ESLint v9** for code quality with flat config structure and Svelte plugin +- **Cloudflare Adapter** for deployment as Cloudflare Workers with assets binding ### Prerequisites - Node.js 18.0.0 or higher (currently uses Node.js 20+) @@ -98,38 +118,40 @@ After making changes, always test these key scenarios: ### CI/CD Pipeline The repository includes GitHub Actions workflow (`.github/workflows/ci.yml`) that runs on every push and pull request: -- **Linting**: ESLint checks for code quality (includes Svelte components) -- **Type Checking**: Svelte type checking validates components and TypeScript -- **Build**: Ensures the project builds successfully +- **Linting**: ESLint v9 checks for code quality (includes Svelte components and TypeScript) +- **Type Checking**: SvelteKit sync and Svelte type checking validates components and TypeScript +- **Build**: Ensures the project builds successfully with SSR bundle generation - **Artifact Upload**: Stores build output for review ### Working with Workout Templates -- Training blocks are defined in `src/blockTemplates.ts` +- Training blocks are defined in `src/lib/blockTemplates.ts` - Each block contains weeks, and each week contains days with different workout types - Workout types include: strength, liss (cardio), hiit, rest, deload, hypertrophy -- Exercise database and one-rep max calculations are handled in components and utils +- Exercise database and one-rep max calculations are handled in API routes and client stores +- API endpoints provide RESTful access to all workout data and state ### Styling and Customization - Uses Tailwind CSS utility classes for styling - Custom styles can be added to `src/app.css` - Tailwind configuration in `tailwind.config.js` -- PWA theming configured in `vite.config.ts` and `index.html` +- PWA theming configured in `vite.config.ts` and `src/app.html` ### Common Command Outputs #### ls -la (repo root) ``` -.eslintrc.cjs +eslint.config.js .git/ .github/ .gitignore README.md +_headers index.html package-lock.json package.json postcss.config.js -public/ src/ +static/ svelte.config.js tailwind.config.js tsconfig.json @@ -141,30 +163,33 @@ wrangler.jsonc #### package.json scripts ```json { - "dev": "vite", - "build": "vite build", + "dev": "vite dev", + "build": "npx svelte-kit sync && vite build", "preview": "vite preview", + "sync": "npx svelte-kit sync", "lint": "eslint . --ext ts,js,svelte --report-unused-disable-directives --max-warnings 0", "lint:fix": "eslint . --ext ts,js,svelte --fix", - "type-check": "svelte-check --tsconfig tsconfig.json" + "type-check": "npx svelte-kit sync && svelte-check --tsconfig tsconfig.json" } ``` ### Environment and Dependencies - No additional SDKs required beyond Node.js 18+ - All dependencies are managed via npm and defined in package.json -- Build outputs to `dist/` directory +- Build outputs to `.svelte-kit/output/` directory (client and server) - Development server runs on http://localhost:5173 - Production preview runs on http://localhost:4173 ### Timing Expectations -- `npm install`: ~45 seconds -- `npm run build`: ~6.5 seconds total (Vite build with Svelte compilation) +- `npm install`: ~20-25 seconds +- `npm run build`: ~15-20 seconds total (SvelteKit compilation with SSR bundle) - `npm run lint`: ~1.5 seconds -- `npm run type-check`: ~2 seconds (svelte-check) -- `npm run dev`: <1 second to start server +- `npm run type-check`: ~3-4 seconds (includes svelte-kit sync) +- `npm run dev`: 1-2 seconds to start server +- `npm run sync`: ~1 second ### Known Issues and Warnings - TypeScript version warning in ESLint (does not affect functionality) - Various npm deprecation warnings during install (do not affect build or runtime) -- Svelte 5 is stable but some third-party libraries may not yet support runes syntax \ No newline at end of file +- Svelte 5 is stable but some third-party libraries may not yet support runes syntax +- SvelteKit generates `.svelte-kit/` directory which should be git ignored \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cc993c..39707c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' cache: 'npm' - name: Install dependencies @@ -35,11 +35,4 @@ jobs: run: npm run type-check - name: Build project - run: npm run build - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: build-files - path: dist/ - retention-days: 7 \ No newline at end of file + run: npm run build \ No newline at end of file diff --git a/README.md b/README.md index 6ec19b5..3c3cba4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Unbroken -**Tactical Barbell Tracker** - A modern Svelte 5 application for tracking strength training, cardio workouts, and training blocks following the Tactical Barbell methodology. Built with TypeScript and Vite, ready for deployment on Cloudflare Pages. +**Tactical Barbell Tracker** - A modern SvelteKit application for tracking strength training, cardio workouts, and training blocks following the Tactical Barbell methodology. Built with TypeScript, featuring a comprehensive REST API and server-side rendering, ready for deployment on Cloudflare Pages. ## 📋 Features @@ -44,20 +44,24 @@ ## 📝 Available Scripts -- `npm run dev` - Start development server -- `npm run build` - Build for production +- `npm run dev` - Start SvelteKit development server with hot module replacement +- `npm run build` - Build for production (includes SSR bundle generation) - `npm run preview` - Preview production build locally -- `npm run lint` - Run ESLint +- `npm run sync` - Sync SvelteKit generated files +- `npm run lint` - Run ESLint with Svelte support - `npm run lint:fix` - Run ESLint with auto-fix -- `npm run type-check` - Run Svelte type checking +- `npm run type-check` - Run SvelteKit sync and Svelte type checking ## 🏗️ Tech Stack +- **SvelteKit** - Full-stack web framework with server-side rendering and API routes - **Svelte 5** - Modern reactive framework with runes for state management - **TypeScript** - Type safety and enhanced developer experience - **Vite** - Build tool and dev server with hot module replacement - **Tailwind CSS** - Utility-first CSS framework for responsive design -- **ESLint** - Code linting and quality enforcement +- **ESLint v9** - Code linting with flat config structure +- **Cloudflare Adapter** - Deployment as Cloudflare Workers with assets binding +- **REST API** - Comprehensive API endpoints for workout management - **Tactical Barbell Methodology** - Structured training approach for strength and conditioning ## 🌐 Deployment on Cloudflare Pages @@ -71,9 +75,9 @@ - Select the `Bruno-366/Unbroken` repository 2. **Configure Build Settings:** - - **Framework preset**: `None` (or `Vite` if available) + - **Framework preset**: `SvelteKit` (or `None` if SvelteKit is not available) - **Build command**: `npm run build` - - **Build output directory**: `dist` + - **Build output directory**: `.svelte-kit/output/client` - **Root directory**: `/` (leave empty) - **Node.js version**: `18` or higher @@ -93,9 +97,9 @@ npm run build ``` -2. Upload the `dist` folder contents to Cloudflare Pages using: +2. Upload the `.svelte-kit/output/client` folder contents to Cloudflare Pages using: - Cloudflare Pages dashboard (drag and drop) - - Wrangler CLI: `npx wrangler pages deploy dist` + - Wrangler CLI: `npx wrangler pages deploy .svelte-kit/output/client` ### Custom Domain @@ -107,53 +111,64 @@ ``` Unbroken/ -├── public/ # Static assets -├── src/ # Source code -│ ├── components/ # Svelte components (refactored from monolithic App.svelte) -│ │ ├── CardioWorkouts.svelte # LISS and HIIT workout rendering -│ │ ├── StrengthWorkouts.svelte # Strength/hypertrophy workouts with warm-up sets -│ │ ├── RestWorkouts.svelte # Rest and deload workout rendering -│ │ ├── History.svelte # Workout history display -│ │ ├── TrainingPlan.svelte # Training blocks drag & drop management -│ │ ├── ExerciseDatabase.svelte # 1RM and 10RM exercise input management -│ │ ├── RestTimer.svelte # Rest timer with visual feedback -│ │ └── ResetProgress.svelte # Reset confirmation modal -│ ├── App.svelte # Main App component with reactive state management -│ ├── types.ts # Centralized TypeScript interfaces and types -│ ├── utils.ts # Shared utility functions (weight calculations, notifications) -│ ├── blockTemplates.ts # Training block templates and configurations -│ ├── main.ts # Entry point -│ └── app.css # Global styles with Tailwind CSS -├── .github/ # GitHub Actions workflows -├── dist/ # Build output (generated) -├── index.html # HTML template -├── package.json # Dependencies and scripts -├── tsconfig.json # TypeScript configuration -├── vite.config.ts # Vite configuration -├── wrangler.jsonc # Cloudflare Pages configuration -├── tailwind.config.js # Tailwind CSS configuration -├── postcss.config.js # PostCSS configuration -├── svelte.config.js # Svelte configuration -└── .eslintrc.cjs # ESLint configuration +├── static/ # Static assets (icons, favicons) +├── src/ # Source code +│ ├── routes/ # SvelteKit file-based routing +│ │ ├── +layout.svelte # Main layout with navigation +│ │ ├── +layout.ts # Layout data loading +│ │ ├── +page.svelte # Overview page (home) +│ │ ├── api/ # REST API endpoints +│ │ │ ├── exercises/ # Exercise management endpoints +│ │ │ ├── training-blocks/ # Training block endpoints +│ │ │ ├── training-plan/ # Training plan endpoints +│ │ │ ├── workout/ # Workout state and completion endpoints +│ │ │ └── history/ # Workout history endpoints +│ │ ├── workout/ # Workout page +│ │ │ ├── +page.svelte # Strength/cardio workout interface +│ │ │ └── +page.ts # Workout page data loading +│ │ ├── history/ # History page +│ │ │ └── +page.svelte # Workout history display +│ │ └── settings/ # Settings page +│ │ └── +page.svelte # Exercise database and training plan management +│ ├── lib/ # Shared library code (SvelteKit convention) +│ │ ├── blockTemplates.ts # Training block templates and configurations +│ │ ├── stores.ts # Client-side reactive stores +│ │ ├── types.ts # Centralized TypeScript interfaces +│ │ └── utils.ts # Shared utility functions (weight calculations, notifications) +│ ├── app.html # HTML template with PWA meta tags +│ ├── app.d.ts # SvelteKit app type definitions +│ └── app.css # Global styles with Tailwind CSS +├── .github/ # GitHub Actions workflows +├── .svelte-kit/ # SvelteKit generated files (git ignored) +├── eslint.config.js # ESLint v9 flat configuration +├── package.json # Dependencies and scripts +├── tsconfig.json # TypeScript configuration +├── vite.config.ts # Vite configuration with SvelteKit +├── wrangler.jsonc # Cloudflare Pages configuration +├── tailwind.config.js # Tailwind CSS configuration +├── postcss.config.js # PostCSS configuration +└── svelte.config.js # Svelte and SvelteKit configuration ``` ### Component Architecture -The application has been built with Svelte 5's modern reactive architecture using runes for state management: +The application has been built with SvelteKit's full-stack architecture and Svelte 5's modern reactive patterns: -- **Reactive State Management**: Svelte 5 runes ($state, $derived, $effect) provide automatic reactivity -- **Component Composition**: Each component handles a specific aspect of functionality -- **Type Safety**: Comprehensive TypeScript interfaces ensure code reliability -- **Reusability**: Components are designed to be easily testable and modifiable -- **Maintainability**: Svelte's compile-time optimizations and clean syntax improve maintainability +- **SvelteKit Framework**: File-based routing with dedicated pages for each section +- **REST API**: Comprehensive server-side API endpoints for all data operations +- **Server-Side Rendering**: Optimized initial page loads with SSR capabilities +- **Reactive State Management**: Svelte 5 runes ($state, $derived, $effect) with client-side stores +- **Type Safety**: Comprehensive TypeScript interfaces shared between client and server +- **Modular Architecture**: Clear separation between routes, API endpoints, and shared utilities +- **Progressive Enhancement**: Works with and without JavaScript enabled ## 🚨 CI/CD The repository includes GitHub Actions workflow that runs on every push and pull request: -- **Linting**: ESLint checks for code quality (Svelte components included) -- **Type Checking**: Svelte type checking validates components and TypeScript -- **Build**: Ensures the project builds successfully +- **Linting**: ESLint v9 checks for code quality (Svelte components and TypeScript) +- **Type Checking**: SvelteKit sync and Svelte type checking validates components and TypeScript +- **Build**: Ensures the project builds successfully with SSR bundle generation - **Artifact Upload**: Stores build output for review ## 🛠️ Customization @@ -168,38 +183,44 @@ The repository includes GitHub Actions workflow that runs on every push and pull ### Additional Dependencies ```bash -# Example: Add a UI library (compatible with Tailwind and Svelte) +# Example: Add a UI library (compatible with Tailwind and SvelteKit) npm install @floating-ui/dom -# Example: Add routing (for multi-page functionality) -npm install svelte-spa-router +# Example: Add form handling and validation for SvelteKit +npm install @sveltejs/enhanced:$form -# Example: Add form handling and validation -npm install felte @felte/validator-zod zod +# Example: Add database integration +npm install drizzle-orm @libsql/client -# Example: Add state management (if needed for larger scale) -npm install svelte/store +# Example: Add authentication +npm install @auth/sveltekit # Example: Add date/time utilities npm install date-fns + +# Example: Add additional SvelteKit adapters +npm install @sveltejs/adapter-vercel @sveltejs/adapter-netlify ``` ### Tailwind CSS Customization - Modify `tailwind.config.js` to extend the theme, add custom colors, or configure plugins - Add custom utilities or components in `src/app.css` - Use Tailwind IntelliSense extension in VS Code for better development experience -- Svelte components work seamlessly with Tailwind's utility classes +- SvelteKit pages and components work seamlessly with Tailwind's utility classes ### Environment Variables Create `.env` files for different environments: -- `.env.local` - Local development +- `.env` - Environment variables for all environments +- `.env.local` - Local development (git ignored) - `.env.production` - Production builds ## 📚 Resources -- [Vite Documentation](https://vitejs.dev/) +- [SvelteKit Documentation](https://kit.svelte.dev/) - [Svelte 5 Documentation](https://svelte.dev/) +- [Vite Documentation](https://vitejs.dev/) - [Cloudflare Pages Documentation](https://developers.cloudflare.com/pages/) +- [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers/) - [TypeScript Documentation](https://www.typescriptlang.org/) - [Tailwind CSS Documentation](https://tailwindcss.com/) - [Tactical Barbell Official](https://www.tacticalbarbell.com/) - Learn about the training methodology diff --git a/package-lock.json b/package-lock.json index 5e513dc..35ee01b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,12 +14,12 @@ "lucide-svelte": "^0.446.0" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "@tailwindcss/postcss": "^4.1.12", "@typescript-eslint/eslint-plugin": "^8.14.0", "@typescript-eslint/parser": "^8.14.0", "autoprefixer": "^10.4.21", - "canvas": "^3.1.2", "eslint": "^9.15.0", "eslint-plugin-svelte": "^2.45.0", "globals": "^15.13.0", @@ -34,7 +34,7 @@ "vite-plugin-pwa": "^1.0.3" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@alloc/quick-lru": { @@ -4367,27 +4367,6 @@ "dev": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/baseline-browser-mapping": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.3.tgz", @@ -4398,18 +4377,6 @@ "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/blake3-wasm": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", @@ -4474,31 +4441,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4587,21 +4529,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/canvas": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.0.tgz", - "integrity": "sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^7.0.0", - "prebuild-install": "^7.1.3" - }, - "engines": { - "node": "^18.12.0 || >= 20.9.0" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4858,32 +4785,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4996,16 +4897,6 @@ "dev": true, "license": "ISC" }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -5531,16 +5422,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/exsolve": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", @@ -5743,13 +5624,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT" - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -5902,13 +5776,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, - "license": "MIT" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -6133,27 +6000,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -6210,13 +6056,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -7238,19 +7077,6 @@ "node": ">=10.0.0" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/miniflare": { "version": "4.20250906.1", "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250906.1.tgz", @@ -7727,16 +7553,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -7776,13 +7592,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "license": "MIT" - }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -7825,13 +7634,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "dev": true, - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7839,26 +7641,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-abi": { - "version": "3.77.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.77.0.tgz", - "integrity": "sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "license": "MIT" - }, "node_modules/node-releases": { "version": "2.0.21", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", @@ -8231,33 +8013,6 @@ "dev": true, "license": "MIT" }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8281,17 +8036,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -8333,47 +8077,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -8935,53 +8638,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-swizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", @@ -9089,16 +8745,6 @@ "npm": ">=6" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -9434,43 +9080,6 @@ "node": ">=18" } }, - "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -9616,19 +9225,6 @@ "license": "0BSD", "optional": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 69ad452..cf4096a 100644 --- a/package.json +++ b/package.json @@ -19,12 +19,12 @@ "lucide-svelte": "^0.446.0" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "@tailwindcss/postcss": "^4.1.12", "@typescript-eslint/eslint-plugin": "^8.14.0", "@typescript-eslint/parser": "^8.14.0", "autoprefixer": "^10.4.21", - "canvas": "^3.1.2", "eslint": "^9.15.0", "eslint-plugin-svelte": "^2.45.0", "globals": "^15.13.0", @@ -39,6 +39,6 @@ "vite-plugin-pwa": "^1.0.3" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }