diff --git a/.gitignore b/.gitignore index 1d790d6..3b462cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,23 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. +node_modules -# compiled output -/dist/ -/tmp/ +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build -# dependencies -/bower_components/ -/node_modules/ - -# misc -/.env* -/.pnp* -/.sass-cache -/.eslintcache -/connect.lock -/coverage/ -/libpeerconnection.log -/npm-debug.log* -/testem.log -/yarn-error.log +# OS +.DS_Store +Thumbs.db -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/package.json.ember-try +# Env +.env +.env.* +!.env.example +!.env.test -.DS_Store +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.prettierignore b/.prettierignore index 9221655..7d74fe2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,21 +1,9 @@ -# unconventional js -/blueprints/*/files/ -/vendor/ - -# compiled output -/dist/ -/tmp/ - -# dependencies -/bower_components/ -/node_modules/ - -# misc -/coverage/ -!.* -.eslintcache - -# ember-try -/.node_modules.ember-try/ -/bower.json.ember-try -/package.json.ember-try +# Package Managers +package-lock.json +pnpm-lock.yaml +yarn.lock +bun.lock +bun.lockb + +# Miscellaneous +/static/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..3f7802c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,15 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..4d5e64f --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode", "esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] +} diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..6219640 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,709 @@ +# You Are A Tree — Build Plan & Cheatsheet + +> A meditative idle/incremental game. You are a tree. Survive as many cycles as possible by growing, adapting, and giving back to the systems that sustain you. + +--- + +## Table of Contents + +1. [Concept Summary](#concept-summary) +2. [Tech Stack](#tech-stack) +3. [Architecture Overview](#architecture-overview) +4. [The Game Clock](#the-game-clock) +5. [The Game Loop](#the-game-loop) +6. [HP Economy](#hp-economy) +7. [The Soil System](#the-soil-system) +8. [Seasonal Design](#seasonal-design) +9. [Scheduled Events](#scheduled-events) +10. [The Math Cheatsheet](#the-math-cheatsheet) +11. [Build Phases](#build-phases) +12. [State Management](#state-management) +13. [Persistence & Auth](#persistence--auth) +14. [Visual Layer](#visual-layer) +15. [Balancing Workflow](#balancing-workflow) +16. [Design Principles to Protect](#design-principles-to-protect) + +--- + +## Concept Summary + +- Player is a tree sapling growing through seasonal cycles +- HP is earned by photosynthesis (leaf surface × sunlight) and spent on growth decisions +- The soil ecosystem is a living character — neglect it and it deteriorates, invest in it and it becomes an ally +- Climate starts stable, becomes increasingly volatile over cycles +- **Goal:** survive as many cycles as possible — no win state, just a leaderboard +- **Core lesson:** survival requires giving back to the systems that sustain you + +--- + +## Tech Stack + +| Layer | Choice | Reason | +| --------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| Frontend | Svelte + TypeScript | Push-based reactivity is a natural fit for a game loop; stores update from outside components without hooks or subscriptions | +| State | Svelte stores + plain TS engine | Writable stores for UI-reactive state; game engine is a plain TS class that owns the authoritative state | +| Canvas / Art | PixiJS | 2D rendering, particle systems, fully decoupled from Svelte | +| Animations (UI) | Svelte built-in transitions | `transition:`, `animate:`, spring physics — first-class, no extra library needed | +| Backend | Supabase (free tier) | Auth + Postgres + REST API, near-zero cost | +| Deployment | Vercel | Free, fast CDN, zero config for SvelteKit | +| Noise | simplex-noise | Organic environmental variation | + +--- + +## Architecture Overview + +``` +┌─────────────────────────────────────────┐ +│ Svelte UI Layer │ +│ Panels, menus, decisions, HUD │ +│ Built-in transitions for animations │ +├─────────────────────────────────────────┤ +│ Svelte Writable Stores │ +│ Reactive bridge between engine & UI │ +│ UI subscribes with $ prefix, no hooks │ +├─────────────────────────────────────────┤ +│ Game Engine (plain TS class) │ +│ Tick loop, clock, event queue │ +│ Owns authoritative state │ +│ Pushes to Svelte stores at render rate│ +├─────────────────────────────────────────┤ +│ PixiJS Canvas │ +│ Background art, particles, soil viz │ +│ Mounted once, reads engine state │ +├─────────────────────────────────────────┤ +│ Supabase (optional) │ +│ Auth + JSON save blobs per user │ +└─────────────────────────────────────────┘ +``` + +**Key principle:** The game engine is a plain TypeScript class with no knowledge of Svelte, Pixi, or Supabase. It owns authoritative game state internally and pushes snapshots to Svelte stores for the UI to render. Player actions call engine methods directly. This separation means: + +- The tick loop never fights a framework's rendering model +- Player actions (spend HP, invest in soil) are synchronous engine calls — no UI state round-trips +- The engine can be tested in isolation +- Future multiplayer is an infrastructure problem, not a logic rewrite + +--- + +## The Game Clock + +Time is **cyclical**, not linear. No timestamps. No relationship to real time. + +```typescript +type GameClock = { + cycle: number; // which year we're on (integer, ever-increasing) + position: number; // 0.0–1.0, position within current cycle +}; + +// Derived helpers +const getSeason = (pos: number): Season => { + if (pos < 0.25) return "spring"; + if (pos < 0.5) return "summer"; + if (pos < 0.75) return "autumn"; + return "winter"; +}; + +const getDay = (pos: number, daysPerCycle = 120): number => + Math.floor(pos * daysPerCycle) + 1; + +// Advancing the clock +function advanceClock( + clock: GameClock, + elapsed: number, + speedMultiplier: number, +): GameClock { + const tickSize = (elapsed / CYCLE_DURATION_MS) * speedMultiplier; + const newPosition = clock.position + tickSize; + + if (newPosition >= 1.0) { + return { cycle: clock.cycle + 1, position: newPosition - 1.0 }; + } + return { ...clock, position: newPosition }; +} +``` + +**Why this works:** + +- Speed-up is just a multiplier — no special cases +- Scheduled events fire at `position` thresholds, not timestamps +- Cycle count gives long-term progression without polluting the seasonal feel +- No timezone, DST, or system clock issues + +--- + +## The Game Loop + +The engine is a plain TypeScript class. It has no dependency on Svelte — it pushes state snapshots to a writable store at render rate, not tick rate. + +```typescript +// engine.ts +import { gameState } from "./stores"; + +const TICK_MS = 100; + +class GameEngine { + private state: GameState = initialState; + private lastTick: number = 0; + private animFrame: number | null = null; + + begin(initialClock?: Partial) { + this.state = { + ...initialState, + clock: { ...DEFAULT_CLOCK, ...initialClock }, + phase: "running", + }; + this.lastTick = Date.now(); + this.scheduleNextTick(); + this.setupVisibilityPause(); + } + + private tick() { + const now = Date.now(); + const elapsed = now - this.lastTick; + + if (elapsed >= TICK_MS && this.state.phase === "running") { + this.lastTick = now; + const prevPosition = this.state.clock.position; + this.state = advanceGameState(this.state, elapsed); + processEvents(prevPosition, this.state.clock.position, this.state); + gameState.set(this.state); // push to Svelte store — UI updates here + } + + this.animFrame = requestAnimationFrame(() => this.tick()); + } + + // Player actions — called directly, no UI state round-trip + spendHP(action: PlayerAction) { + this.state = applyPlayerAction(this.state, action); + gameState.set(this.state); + } + + resolveEvent(choice: Choice) { + this.state = applyEventChoice(this.state, choice); + this.state = { ...this.state, phase: "running", pendingEvent: null }; + gameState.set(this.state); + } + + private setupVisibilityPause() { + document.addEventListener("visibilitychange", () => { + if (document.hidden) { + this.state = { ...this.state, phase: "paused" }; + gameState.set(this.state); + } else if (this.state.phase === "paused") { + this.lastTick = Date.now(); // reset — no catch-up + this.state = { ...this.state, phase: "running" }; + gameState.set(this.state); + } + }); + } + + private scheduleNextTick() { + this.animFrame = requestAnimationFrame(() => this.tick()); + } + + getState(): GameState { + return this.state; + } + serialize(): SaveBlob { + return { version: 1, savedAt: Date.now(), gameState: this.state }; + } + loadFrom(blob: SaveBlob) { + this.state = blob.gameState; + gameState.set(this.state); + } +} + +export const engine = new GameEngine(); +``` + +```typescript +// stores.ts +import { writable } from "svelte/store"; +export const gameState = writable(initialState); +``` + +```svelte + + + +{#if $gameState.phase === 'awaiting_input'} + engine.resolveEvent(e.detail)} + /> +{:else} + + engine.spendHP(e.detail)} /> +{/if} +``` + +**Why this works:** + +- The engine ticks freely at 100ms intervals — Svelte only re-renders when `gameState.set()` is called +- Player actions (`spendHP`, `resolveEvent`) are synchronous and immediate — no async state round-trips +- `phase === 'awaiting_input'` pauses the engine's tick logic; Svelte reactively swaps the UI +- `visibilitychange` resets `lastTick` on return — no catch-up, no offline progression + +--- + +## HP Economy + +HP is the player's energy currency — earned by photosynthesis, spent on decisions. + +```typescript +type TreeState = { + hp: number; + leafSurface: number; // 0–1, determines photosynthesis rate + rootDepth: number; // 0–1, determines soil interaction quality + rootBreadth: number; // 0–1, determines moisture access + branchCount: number; // integer, determines max leaf surface + age: number; // cycles survived +}; + +function photosynthesisIncome( + tree: TreeState, + soil: SoilState, + clock: GameClock, + noise: number, +): number { + const sunlight = getSeasonalSunlight(clock) * (0.85 + 0.15 * noise); // noisy + const soilBonus = getSoilBonus(soil); // 0–1 multiplier + return tree.leafSurface * sunlight * soilBonus; +} +``` + +**Budget sketch (tune this before coding):** + +| Season | Base Income | Maintenance | Net Margin | +| ------ | ----------- | ----------- | ------------------ | +| Spring | Medium | Low | Positive — invest | +| Summer | High | Medium | Positive — grow | +| Autumn | Low | Medium | Thin — prepare | +| Winter | Very Low | High | Negative — survive | + +**Design target:** Player should be operating near-zero margin in winter. Decisions only feel meaningful under scarcity. + +--- + +## The Soil System + +The soil is a living character with its own internal dynamics. Keep each relationship simple; let interactions create complexity. + +```typescript +type SoilState = { + organicMatter: number; // 0–1, primary resource pool + microbialActivity: number; // 0–1, drives nutrient cycling + moisture: number; // 0–1, affected by season and roots + fungalNetwork: number; // 0–1, the mycorrhizal relationship +}; +``` + +### Internal Dynamics (per tick) + +```typescript +function updateSoil( + soil: SoilState, + tree: TreeState, + clock: GameClock, + treeInvestment: number, +): SoilState { + const season = getSeason(clock.position); + + // Organic matter: replenished by fungal network + leaf litter, depleted over time + const organicDecay = 0.0002; + const fungalReplenishment = soil.fungalNetwork * 0.0003; + const leafLitter = season === "autumn" ? 0.0005 : 0.0001; + const newOrganicMatter = clamp( + soil.organicMatter - organicDecay + fungalReplenishment + leafLitter, + ); + + // Microbial activity: depends on organic matter AND moisture + const targetMicrobial = soil.organicMatter * soil.moisture; + const newMicrobial = lerp(soil.microbialActivity, targetMicrobial, 0.01); // lags behind + + // Moisture: seasonal baseline + root breadth influence + const seasonalMoisture = getSeasonalMoisture(season); + const rootInfluence = tree.rootBreadth * 0.1; + const newMoisture = clamp( + lerp(soil.moisture, seasonalMoisture + rootInfluence, 0.005), + ); + + // Fungal network: grows with tree investment, decays without it + const fungalGrowth = treeInvestment * 0.01; + const fungalDecay = 0.0003; + const newFungal = clamp(soil.fungalNetwork + fungalGrowth - fungalDecay); + + return { + organicMatter: newOrganicMatter, + microbialActivity: newMicrobial, + moisture: newMoisture, + fungalNetwork: newFungal, + }; +} +``` + +### Soil → Tree Benefits (threshold-based, not smooth) + +```typescript +function getSoilBonus(soil: SoilState): number { + const health = + (soil.organicMatter + soil.microbialActivity + soil.fungalNetwork) / 3; + + if (health > 0.7) return 1.4; // thriving: meaningful bonus + if (health > 0.5) return 1.0; // healthy: baseline + if (health > 0.3) return 0.7; // stressed: noticeable penalty + return 0.3; // collapsing: severe penalty +} +``` + +**Important:** The tipping points should feel surprising. The player should not see "0.5 threshold" — they should just feel the floor drop out. + +### Lag Effects + +Soil consequences should arrive **1–2 seasons after** the cause. Track a rolling average or use a delayed variable. This is the mechanic that teaches "ecosystems have memory." + +--- + +## Seasonal Design + +Each season has a distinct mechanical identity and emotional register. + +| Season | Sunlight | Moisture | Maintenance Cost | Strategic Priority | +| ------ | -------- | -------- | ---------------- | --------------------------------- | +| Spring | Medium | High | Low | Grow aggressively | +| Summer | High | Low | Medium | Expand leaf surface; drought risk | +| Autumn | Low | Medium | Medium | Invest in soil before winter | +| Winter | Very Low | Medium | High | Survive; soil investment pays off | + +### Milestone Years + +Every N cycles, a significant environmental event punctuates the meditative rhythm: + +- Cycle 3: First drought summer +- Cycle 5: Early frost (winter arrives at 0.6 instead of 0.75) +- Cycle 8: Pest outbreak — leaf surface temporarily reduced +- Cycle 12+: Climate volatility increases permanently (noise amplitude scales with `cycle`) + +```typescript +// Climate volatility increases over time +const volatility = Math.min(0.1 + cycle * 0.008, 0.5); +const sunlight = baseSunlight + volatility * simplexNoise(gameTime); +``` + +--- + +## Scheduled Events + +Events fire at `position` thresholds, not timestamps. This handles speed-up naturally. + +```typescript +type ScheduledEvent = { + id: string; + triggerPosition: number; // 0.0–1.0 within cycle + triggerCycle?: number; // if undefined, fires every cycle + type: EventType; + payload?: unknown; +}; + +function processEvents( + prevPos: number, + nextPos: number, + cycle: number, + events: ScheduledEvent[], +) { + // Handle cycle wrap (prevPos > nextPos means we crossed 1.0) + const wrapped = nextPos < prevPos; + + const due = events.filter((e) => { + const matchesCycle = + e.triggerCycle === undefined || e.triggerCycle === cycle; + const inWindow = wrapped + ? e.triggerPosition > prevPos || e.triggerPosition <= nextPos + : e.triggerPosition > prevPos && e.triggerPosition <= nextPos; + return matchesCycle && inWindow; + }); + + // Sort by position to preserve causality at high speed + due.sort((a, b) => a.triggerPosition - b.triggerPosition); + due.forEach(handleEvent); +} +``` + +**"Pause for user input" events:** transition `gamePhase` to `'awaiting_input'`. Stop advancing clock. Resume on player action. + +```typescript +type GamePhase = "running" | "awaiting_input" | "paused"; +``` + +--- + +## The Math Cheatsheet + +### Curve Types + +```typescript +// Linear — default, use first +const value = base - decayRate * elapsed; + +// Exponential decay — neglect compounds +soil.health *= 0.999; // loses ~0.1% per tick, accelerates toward 0 + +// Logistic (S-curve) — natural growth and recovery +const logistic = (x: number, k = 10) => 1 / (1 + Math.exp(-k * (x - 0.5))); + +// Lerp — smooth approach to target (good for soil lag) +const lerp = (a: number, b: number, t: number) => a + (b - a) * t; + +// Clamp — always normalize outputs +const clamp = (v: number, min = 0, max = 1) => Math.max(min, Math.min(max, v)); +``` + +### Noise + +```typescript +import { createNoise2D } from "simplex-noise"; +const noise2D = createNoise2D(); + +// Organic sunlight variation +const sunlight = 0.7 + 0.3 * noise2D(clock.position * 3, clock.cycle * 0.1); + +// Layered noise (weather patterns + daily variation) +const weather = + 0.6 * noise2D(clock.position * 2, clock.cycle) + + 0.4 * noise2D(clock.position * 10, clock.cycle); +``` + +### Key Formulas + +```typescript +// Photosynthesis income +hp_income = leafSurface × sunlight × soilBonus × seasonMultiplier + +// Soil composite health (used for display and thresholds) +soilHealth = (organicMatter + microbialActivity + fungalNetwork) / 3 + +// Climate volatility (scales with age) +volatility = clamp(0.1 + cycle * 0.008, 0, 0.5) + +// Leaderboard score +score = cycle + (soilHealth * 0.5) // reward cycles survived + ecosystem stewardship +``` + +--- + +## Build Phases + +### Phase 1 — The Clock and Loop + +**Goal:** Time advances. Seasons cycle. Debug view only. + +- Game engine class with clock, tick loop, `begin()` method +- `gameState` Svelte store wired to engine +- `visibilitychange` pause/resume in engine +- Speed multiplier (slow, normal, fast) +- Svelte debug component showing raw store values + +**Done when:** You can watch a full cycle pass at multiple speeds and see it wrap correctly. + +### Phase 2 — The HP Economy + +**Goal:** Basic photosynthesis loop is playable. Decisions exist. + +- `leafSurface`, `rootDepth` as tree stats +- HP income per tick +- 2–3 spending options (grow branch, grow root, idle) +- Seasonal sunlight multiplier +- No soil yet + +**Done when:** You're making real tradeoffs and some seasons feel harder than others. + +### Phase 3 — The Soil as Character + +**Goal:** Soil has internal dynamics. Neglect has consequences. + +- Full `SoilState` with interactions +- Tree investment mechanic +- Threshold-based soil bonus +- Lag effects (1–2 season delay on consequences) +- Visible soil feedback (even if abstract) + +**Done when:** You've neglected soil for two cycles and felt it hurt. Then recovered it. Tune obsessively here. + +### Phase 4 — Seasonal Differentiation + Events + +**Goal:** Each season feels distinct. Events fire correctly at high speed. + +- Per-season constants tuned +- Scheduled event queue +- Milestone year events (drought, frost, pests) +- `awaiting_input` phase for player decisions +- Climate volatility scaling with cycle count + +**Done when:** Year 5 feels meaningfully harder than Year 1. + +### Phase 5 — Art and Feel + +**Goal:** The game feels like itself. + +- PixiJS canvas with particle background (mounted via Svelte `onMount`) +- Seasonal visual transitions (color palette, particle behavior) +- Svelte built-in transitions for panel animations (`transition:fly`, `transition:fade`) +- `svelte/motion` spring values for physical UI feedback +- Sound design (ambient, seasonal, soil health feedback) +- Soil visualization (abstract noise — the player senses something is there) + +**Done when:** You'd show it to someone without apologizing. + +### Phase 6 — Persistence and Leaderboard + +**Goal:** Save/load works. Scores are recorded. + +- Supabase auth (optional login) +- Game state serialized to JSON, saved as blob +- `localStorage` autosave as fallback for logged-out play +- Cycle count leaderboard +- Load saved state on login + +**Done when:** You can close the tab, return, and continue or start fresh with your score recorded. + +--- + +## State Management + +State lives in two places with clearly defined roles: + +**The engine** owns authoritative game state as a plain TypeScript object. It is the source of truth. Nothing mutates it except engine methods. + +**Svelte stores** are a reactive snapshot of engine state for the UI. They are write-only from the engine's perspective — the UI reads them with `$`, never writes back. + +```typescript +// stores.ts — UI-reactive snapshots only +import { writable } from "svelte/store"; + +export const gameState = writable(initialState); + +// Optionally, derived stores for expensive computations +import { derived } from "svelte/store"; +export const soilHealth = derived( + gameState, + ($s) => + ($s.soil.organicMatter + + $s.soil.microbialActivity + + $s.soil.fungalNetwork) / + 3, +); +``` + +```typescript +// The authoritative state shape — lives inside the engine class +type GameState = { + clock: GameClock; + phase: "idle" | "running" | "awaiting_input" | "paused"; + tree: TreeState; + soil: SoilState; + events: ScheduledEvent[]; + speedMultiplier: number; + pendingEvent: GameEvent | null; + soilHistory: number[]; // rolling window for lag effects +}; +``` + +**Rules:** + +- All state transitions are pure functions: `(state, input) => newState` +- Never mutate state directly — always return new objects (spread operator) +- Serializing to JSON must always work — no functions, no circular refs +- All tunable values live in `constants.ts` — never hardcode rates inline + +```typescript +// constants.ts — tune here, never in logic files +export const CONSTANTS = { + CYCLE_DURATION_MS: 5 * 60 * 1000, // 5 real minutes per cycle + ORGANIC_DECAY_RATE: 0.0002, + FUNGAL_DECAY_RATE: 0.0003, + SOIL_LAG_SEASONS: 1.5, + VOLATILITY_PER_CYCLE: 0.008, + // ... +}; +``` + +--- + +## Persistence & Auth + +**Logged-out flow:** Autosave to `localStorage` every 30 seconds. On load, restore from `localStorage` if present. + +**Logged-in flow:** On login, fetch save blob from Supabase. On meaningful actions and periodic intervals, push updated state blob. `localStorage` remains as a fast cache. + +```typescript +// Save blob shape +type SaveBlob = { + version: number; // for migration handling + savedAt: number; // real timestamp for display + gameState: GameState; +}; +``` + +**Leaderboard:** Simple Supabase table — `user_id`, `cycles_survived`, `final_soil_health`, `achieved_at`. Query top N on game over screen. + +--- + +## Visual Layer + +PixiJS mounts once into a DOM node in a Svelte `onMount` and runs its own loop, reading directly from the engine: + +```svelte + + + +
+``` + +No Strict Mode double-invocation issues. `onMount` runs exactly once. + +**Soil visualization:** Use particle density, color warmth, and animation speed to reflect soil health — without ever showing a number. The player should _sense_ the soil's state before they understand it. + +**Seasonal palette:** Transition background color, particle color, and ambient light smoothly as `clock.position` advances. No hard cuts. + +**Svelte transitions for UI panels:** Use built-in `transition:fly` or `transition:fade` for panel entry/exit. Spring physics via `svelte/motion` for any value that should feel physical (HP meter, soil indicator). + +--- + +## Balancing Workflow + +1. **Spreadsheet first.** Model a full 4-season cycle with proposed numbers before writing code. Simulate "good player" vs "neglectful player" runs. +2. **Debug overlay always on during dev.** Show all raw 0–1 values on screen. You'll spend hours watching these. +3. **Expose all constants as runtime-tuneable** — a dev panel that lets you change decay rates without reloading saves days of iteration. +4. **Plot your curves.** Use [Desmos](https://desmos.com) to visualize curve shapes before implementing. Check that thresholds land where you want them. +5. **Playtest with soil neglect deliberately.** The neglect → collapse path needs to feel instructive, not punishing. Tune until it does. + +--- + +## Design Principles to Protect + +These are easy to erode under the pressure of adding features. Revisit this list often. + +- **The tree can die, but struggles visibly first.** Death should feel like the end of a long effort, not a sudden punishment. The tree deteriorates slowly, carries the marks of its decisions, and dies later than it looks like it will. +- **Decisions are infrequent but weighty.** Don't ask for input every few seconds. Let the game breathe. The pause-for-input moments should feel like they matter. +- **Soil complexity is discovered, not explained.** The player should notice something is there before understanding it. Abstract visualization, not a health bar and a tooltip. +- **Lag effects are features.** Consequences arriving 1–2 seasons late is the lesson. Don't shorten this to make the game feel more responsive. +- **Simplicity in individual mechanics, complexity in interactions.** Resist writing complicated formulas. Write simple ones that talk to each other. +- **The leaderboard is not the game.** Build the solo experience until it's worth playing for its own sake before optimizing for score. diff --git a/README.md b/README.md index 0d961ea..71282bb 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,33 @@ -# you-are-a-tree +# You Are A Tree -This README outlines the details of collaborating on this Ember application. -A short introduction of this app could easily go here. +You Are A Tree is a meditative nature game. You are a tree. Survive as many cycles as possible by growing, adapting, and giving back to the systems that sustain you. -## Prerequisites +## Developing -You will need the following things properly installed on your computer. +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: -* [Git](https://git-scm.com/) -* [Node.js](https://nodejs.org/) (with npm) -* [Ember CLI](https://ember-cli.com/) -* [Google Chrome](https://google.com/chrome/) +```sh +npm run dev -## Installation +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` -* `git clone ` this repository -* `cd you-are-a-tree` -* `npm install` +## Building -## Running / Development +To create a production version of your app: -* `ember serve` -* Visit your app at [http://localhost:4200](http://localhost:4200). -* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests). +```sh +npm run build +``` -### Code Generators +You can preview the production build with `npm run preview`. -Make use of the many generators for code, try `ember help generate` for more details +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. -### Running Tests +To recreate this project with the same configuration: -* `ember test` -* `ember test --server` - -### Linting - -* `npm run lint` -* `npm run lint:fix` - -### Building - -* `ember build` (development) -* `ember build --environment production` (production) - -### Deploying - -Specify what it takes to deploy your app. - -## Further Reading / Useful Links - -* [ember.js](https://emberjs.com/) -* [ember-cli](https://ember-cli.com/) -* Development Browser Extensions - * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) - * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) +```sh +# recreate this project +pnpm dlx sv@0.12.5 create --template minimal --types ts --add prettier vitest="usages:unit,component" eslint --install pnpm you-are-a-tree +``` diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..9690379 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,39 @@ +import prettier from 'eslint-config-prettier'; +import path from 'node:path'; +import { includeIgnoreFile } from '@eslint/compat'; +import js from '@eslint/js'; +import svelte from 'eslint-plugin-svelte'; +import { defineConfig } from 'eslint/config'; +import globals from 'globals'; +import ts from 'typescript-eslint'; +import svelteConfig from './svelte.config.js'; + +const gitignorePath = path.resolve(import.meta.dirname, '.gitignore'); + +export default defineConfig( + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs.recommended, + prettier, + ...svelte.configs.prettier, + { + languageOptions: { globals: { ...globals.browser, ...globals.node } }, + rules: { + // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. + // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + 'no-undef': 'off' + } + }, + { + files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: ['.svelte'], + parser: ts.parser, + svelteConfig + } + } + } +); diff --git a/package.json b/package.json index e05059b..b90a6c2 100644 --- a/package.json +++ b/package.json @@ -1,80 +1,41 @@ { - "name": "you-are-a-tree", - "version": "0.0.0", - "private": true, - "description": "Small description for you-are-a-tree goes here", - "repository": "", - "license": "MIT", - "author": "", - "directories": { - "doc": "doc", - "test": "tests" - }, - "scripts": { - "build": "ember build --environment=production", - "lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'", - "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix", - "lint:hbs": "ember-template-lint .", - "lint:hbs:fix": "ember-template-lint . --fix", - "lint:js": "eslint . --cache", - "lint:js:fix": "eslint . --fix", - "start": "ember serve --port=4300", - "server": "ember server", - "test": "npm-run-all lint test:*", - "test:ember": "ember test" - }, - "devDependencies": { - "@ember/optional-features": "^2.0.0", - "@ember/render-modifiers": "^1.0.2", - "@ember/test-helpers": "^2.2.5", - "@glimmer/component": "^1.0.4", - "@glimmer/tracking": "^1.0.4", - "babel-eslint": "^10.1.0", - "broccoli-asset-rev": "^3.0.0", - "ember-auto-import": "^1.11.2", - "ember-cli": "~3.26.0", - "ember-cli-app-version": "^5.0.0", - "ember-cli-babel": "^7.26.3", - "ember-cli-dependency-checker": "^3.2.0", - "ember-cli-htmlbars": "^5.7.1", - "ember-cli-inject-live-reload": "^2.0.2", - "ember-cli-postcss": "^7.0.2", - "ember-cli-sri": "^2.1.1", - "ember-cli-terser": "^4.0.1", - "ember-concurrency": "^2.1.2", - "ember-d3": "^0.5.1", - "ember-data": "~3.26.0", - "ember-export-application-global": "^2.0.1", - "ember-fetch": "^8.0.4", - "ember-load-initializers": "^2.1.2", - "ember-maybe-import-regenerator": "^0.1.6", - "ember-modal-dialog": "^3.0.3", - "ember-page-title": "^6.2.1", - "ember-qunit": "^5.1.4", - "ember-resolver": "^8.0.2", - "ember-source": "~3.26.1", - "ember-template-lint": "^3.2.0", - "ember-truth-helpers": "^3.0.0", - "ember-welcome-page": "^4.0.0", - "eslint": "^7.23.0", - "eslint-config-prettier": "^8.1.0", - "eslint-plugin-ember": "^10.3.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.3.1", - "game": "^1.0.3", - "loader.js": "^4.7.0", - "npm-run-all": "^4.1.5", - "postcss-cssnext": "^3.1.0", - "postcss-import": "^14.0.2", - "prettier": "^2.2.1", - "qunit": "^2.14.1", - "qunit-dom": "^1.6.0", - "service": "^0.1.4" - }, - "engines": { - "node": "10.* || >= 12" - }, - "ember": { - "edition": "octane" - } + "name": "you-are-a-tree", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --check . && eslint .", + "format": "prettier --write .", + "test:unit": "vitest", + "test": "npm run test:unit -- --run" + }, + "devDependencies": { + "@eslint/compat": "^2.0.2", + "@eslint/js": "^9.39.2", + "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/kit": "^2.50.2", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "@types/node": "^24", + "@vitest/browser-playwright": "^4.0.18", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.14.0", + "globals": "^17.3.0", + "playwright": "^1.58.2", + "prettier": "^3.8.1", + "prettier-plugin-svelte": "^3.4.1", + "svelte": "^5.51.0", + "svelte-check": "^4.4.2", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0", + "vite": "^7.3.1", + "vitest": "^4.0.18", + "vitest-browser-svelte": "^2.0.2" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..dedbb09 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2458 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@eslint/compat': + specifier: ^2.0.2 + version: 2.0.3(eslint@9.39.4) + '@eslint/js': + specifier: ^9.39.2 + version: 9.39.4 + '@sveltejs/adapter-auto': + specifier: ^7.0.0 + version: 7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0))) + '@sveltejs/kit': + specifier: ^2.50.2 + version: 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0)) + '@sveltejs/vite-plugin-svelte': + specifier: ^6.2.4 + version: 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)) + '@types/node': + specifier: ^24 + version: 24.12.0 + '@vitest/browser-playwright': + specifier: ^4.0.18 + version: 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@24.12.0))(vitest@4.0.18) + eslint: + specifier: ^9.39.2 + version: 9.39.4 + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-svelte: + specifier: ^3.14.0 + version: 3.15.1(eslint@9.39.4)(svelte@5.53.9) + globals: + specifier: ^17.3.0 + version: 17.4.0 + playwright: + specifier: ^1.58.2 + version: 1.58.2 + prettier: + specifier: ^3.8.1 + version: 3.8.1 + prettier-plugin-svelte: + specifier: ^3.4.1 + version: 3.5.1(prettier@3.8.1)(svelte@5.53.9) + svelte: + specifier: ^5.51.0 + version: 5.53.9 + svelte-check: + specifier: ^4.4.2 + version: 4.4.5(picomatch@4.0.3)(svelte@5.53.9)(typescript@5.9.3) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.54.0 + version: 8.57.0(eslint@9.39.4)(typescript@5.9.3) + vite: + specifier: ^7.3.1 + version: 7.3.1(@types/node@24.12.0) + vitest: + specifier: ^4.0.18 + version: 4.0.18(@types/node@24.12.0)(@vitest/browser-playwright@4.0.18) + vitest-browser-svelte: + specifier: ^2.0.2 + version: 2.0.2(svelte@5.53.9)(vitest@4.0.18) + +packages: + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/compat@2.0.3': + resolution: {integrity: sha512-SjIJhGigp8hmd1YGIBwh7Ovri7Kisl42GYFjrOyHhtfYGGoLW6teYi/5p8W50KSsawUPpuLOSmsq1bD0NGQLBw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^8.40 || 9 || 10 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@1.1.1': + resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@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==} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@sveltejs/acorn-typescript@1.0.9': + resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/adapter-auto@7.0.1': + resolution: {integrity: sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + + '@sveltejs/kit@2.53.4': + resolution: {integrity: sha512-iAIPEahFgDJJyvz8g0jP08KvqnM6JvdW8YfsygZ+pMeMvyM2zssWMltcsotETvjSZ82G3VlitgDtBIvpQSZrTA==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: ^5.3.3 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + typescript: + optional: true + + '@sveltejs/vite-plugin-svelte-inspector@5.0.2': + resolution: {integrity: sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==} + 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.4': + resolution: {integrity: sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@testing-library/svelte-core@1.0.0': + resolution: {integrity: sha512-VkUePoLV6oOYwSUvX6ShA8KLnJqZiYMIbP2JW2t0GLWLkJxKGvuH5qrrZBV/X7cXFnLGuFQEC7RheYiZOW68KQ==} + engines: {node: '>=16'} + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@typescript-eslint/eslint-plugin@8.57.0': + resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.57.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.57.0': + resolution: {integrity: sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.57.0': + resolution: {integrity: sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.57.0': + resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.57.0': + resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.57.0': + resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.57.0': + resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.57.0': + resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.57.0': + resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.57.0': + resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitest/browser-playwright@4.0.18': + resolution: {integrity: sha512-gfajTHVCiwpxRj1qh0Sh/5bbGLG4F/ZH/V9xvFVoFddpITfMta9YGow0W6ZpTTORv2vdJuz9TnrNSmjKvpOf4g==} + peerDependencies: + playwright: '*' + vitest: 4.0.18 + + '@vitest/browser@4.0.18': + resolution: {integrity: sha512-gVQqh7paBz3gC+ZdcCmNSWJMk70IUjDeVqi+5m5vYpEHsIwRgw3Y545jljtajhkekIpIp5Gg8oK7bctgY0E2Ng==} + peerDependencies: + vitest: 4.0.18 + + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + 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==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + 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'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + 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==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + devalue@5.6.3: + resolution: {integrity: sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-svelte@3.15.1: + resolution: {integrity: sha512-Ao/LGKPFzz8jbLEqa7OMK6LUX/mJRcJbVbIaHKjdheirkwjA/cDLdY1NcIZYscRxrK4FDIOX6IepmXFnhQlDlw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrap@2.2.3: + resolution: {integrity: sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.1: + resolution: {integrity: sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + 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-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + globals@17.4.0: + resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + known-css-properties@0.37.0: + resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + 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 + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pixelmatch@7.1.0: + resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} + hasBin: true + + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} + engines: {node: '>=18'} + hasBin: true + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + + postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} + peerDependencies: + postcss: ^8.4.31 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-svelte@3.5.1: + resolution: {integrity: sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@3.0.1: + resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + svelte-check@4.4.5: + resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte-eslint-parser@1.6.0: + resolution: {integrity: sha512-qoB1ehychT6OxEtQAqc/guSqLS20SlA53Uijl7x375s8nlUT0lb9ol/gzraEEatQwsyPTJo87s2CmKL9Xab+Uw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.30.3} + peerDependencies: + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + svelte@5.53.9: + resolution: {integrity: sha512-MwDfWsN8qZzeP0jlQsWF4k/4B3csb3IbzCRggF+L/QqY7T8bbKvnChEo1cPZztF51HJQhilDbevWYl2LvXbquA==} + engines: {node: '>=18'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.57.0: + resolution: {integrity: sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.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 + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.2: + resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + + vitest-browser-svelte@2.0.2: + resolution: {integrity: sha512-OLJVYoIYflwToFIy3s41pZ9mVp6dwXfYd8IIsWoc57g8DyN3SxsNJ5GB1xWFPxLFlKM+1MPExjPxLaqdELrfRQ==} + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + vitest: ^4.0.0 + + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + +snapshots: + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/compat@2.0.3(eslint@9.39.4)': + dependencies: + '@eslint/core': 1.1.1 + optionalDependencies: + eslint: 9.39.4 + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@1.1.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@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 + + '@polka/url@1.0.0-next.29': {} + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@standard-schema/spec@1.1.0': {} + + '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': + dependencies: + acorn: 8.16.0 + + '@sveltejs/adapter-auto@7.0.1(@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0)))': + dependencies: + '@sveltejs/kit': 2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0)) + + '@sveltejs/kit@2.53.4(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0))': + dependencies: + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)) + '@types/cookie': 0.6.0 + acorn: 8.16.0 + cookie: 0.6.0 + devalue: 5.6.3 + esm-env: 1.2.2 + kleur: 4.1.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + set-cookie-parser: 3.0.1 + sirv: 3.0.2 + svelte: 5.53.9 + vite: 7.3.1(@types/node@24.12.0) + optionalDependencies: + typescript: 5.9.3 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)) + obug: 2.1.1 + svelte: 5.53.9 + vite: 7.3.1(@types/node@24.12.0) + + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)))(svelte@5.53.9)(vite@7.3.1(@types/node@24.12.0)) + deepmerge: 4.3.1 + magic-string: 0.30.21 + obug: 2.1.1 + svelte: 5.53.9 + vite: 7.3.1(@types/node@24.12.0) + vitefu: 1.1.2(vite@7.3.1(@types/node@24.12.0)) + + '@testing-library/svelte-core@1.0.0(svelte@5.53.9)': + dependencies: + svelte: 5.53.9 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/cookie@0.6.0': {} + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.12.0': + dependencies: + undici-types: 7.16.0 + + '@types/trusted-types@2.0.7': {} + + '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.0 + '@typescript-eslint/type-utils': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.0 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.0 + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.0 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) + '@typescript-eslint/types': 8.57.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.57.0': + dependencies: + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/visitor-keys': 8.57.0 + + '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.57.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.57.0': {} + + '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/visitor-keys': 8.57.0 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.57.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.57.0 + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.57.0': + dependencies: + '@typescript-eslint/types': 8.57.0 + eslint-visitor-keys: 5.0.1 + + '@vitest/browser-playwright@4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@24.12.0))(vitest@4.0.18)': + dependencies: + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@24.12.0))(vitest@4.0.18) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)) + playwright: 1.58.2 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@24.12.0)(@vitest/browser-playwright@4.0.18) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/browser@4.0.18(vite@7.3.1(@types/node@24.12.0))(vitest@4.0.18)': + dependencies: + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)) + '@vitest/utils': 4.0.18 + magic-string: 0.30.21 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@24.12.0)(@vitest/browser-playwright@4.0.18) + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/expect@4.0.18': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.12.0))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@24.12.0) + + '@vitest/pretty-format@4.0.18': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.18': + dependencies: + '@vitest/utils': 4.0.18 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.18': {} + + '@vitest/utils@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + tinyrainbow: 3.0.3 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-query@5.3.1: {} + + assertion-error@2.0.1: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + + callsites@3.1.0: {} + + chai@6.2.2: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + cookie@0.6.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + devalue@5.6.3: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-svelte@3.15.1(eslint@9.39.4)(svelte@5.53.9): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@jridgewell/sourcemap-codec': 1.5.5 + eslint: 9.39.4 + esutils: 2.0.3 + globals: 16.5.0 + known-css-properties: 0.37.0 + postcss: 8.5.8 + postcss-load-config: 3.1.4(postcss@8.5.8) + postcss-safe-parser: 7.0.1(postcss@8.5.8) + semver: 7.7.4 + svelte-eslint-parser: 1.6.0(svelte@5.53.9) + optionalDependencies: + svelte: 5.53.9 + transitivePeerDependencies: + - ts-node + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + esm-env@1.2.2: {} + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrap@2.2.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.1 + keyv: 4.5.4 + + flatted@3.4.1: {} + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.5.0: {} + + globals@17.4.0: {} + + has-flag@4.0.0: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + isexe@2.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + known-css-properties@0.37.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + locate-character@3.0.0: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + obug@2.1.1: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pixelmatch@7.1.0: + dependencies: + pngjs: 7.0.0 + + playwright-core@1.58.2: {} + + playwright@1.58.2: + dependencies: + playwright-core: 1.58.2 + optionalDependencies: + fsevents: 2.3.2 + + pngjs@7.0.0: {} + + postcss-load-config@3.1.4(postcss@8.5.8): + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + optionalDependencies: + postcss: 8.5.8 + + postcss-safe-parser@7.0.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-scss@4.0.9(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.53.9): + dependencies: + prettier: 3.8.1 + svelte: 5.53.9 + + prettier@3.8.1: {} + + punycode@2.3.1: {} + + readdirp@4.1.2: {} + + resolve-from@4.0.0: {} + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + semver@7.7.4: {} + + set-cookie-parser@3.0.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.53.9)(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.53.9 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte-eslint-parser@1.6.0(svelte@5.53.9): + dependencies: + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + postcss: 8.5.8 + postcss-scss: 4.0.9(postcss@8.5.8) + postcss-selector-parser: 7.1.1 + semver: 7.7.4 + optionalDependencies: + svelte: 5.53.9 + + svelte@5.53.9: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@types/estree': 1.0.8 + '@types/trusted-types': 2.0.7 + acorn: 8.16.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.3 + esm-env: 1.2.2 + esrap: 2.2.3 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + totalist@3.0.1: {} + + ts-api-utils@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.57.0(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici-types@7.16.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vite@7.3.1(@types/node@24.12.0): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.8 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.12.0 + fsevents: 2.3.3 + + vitefu@1.1.2(vite@7.3.1(@types/node@24.12.0)): + optionalDependencies: + vite: 7.3.1(@types/node@24.12.0) + + vitest-browser-svelte@2.0.2(svelte@5.53.9)(vitest@4.0.18): + dependencies: + '@testing-library/svelte-core': 1.0.0(svelte@5.53.9) + svelte: 5.53.9 + vitest: 4.0.18(@types/node@24.12.0)(@vitest/browser-playwright@4.0.18) + + vitest@4.0.18(@types/node@24.12.0)(@vitest/browser-playwright@4.0.18): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@24.12.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.12.0 + '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@24.12.0))(vitest@4.0.18) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + ws@8.19.0: {} + + yaml@1.10.2: {} + + yocto-queue@0.1.0: {} + + zimmerframe@1.1.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..efc037a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +onlyBuiltDependencies: + - esbuild diff --git a/.editorconfig b/previous-2021/.editorconfig similarity index 100% rename from .editorconfig rename to previous-2021/.editorconfig diff --git a/.ember-cli b/previous-2021/.ember-cli similarity index 100% rename from .ember-cli rename to previous-2021/.ember-cli diff --git a/.eslintignore b/previous-2021/.eslintignore similarity index 100% rename from .eslintignore rename to previous-2021/.eslintignore diff --git a/.eslintrc.js b/previous-2021/.eslintrc.js similarity index 100% rename from .eslintrc.js rename to previous-2021/.eslintrc.js diff --git a/previous-2021/.gitignore b/previous-2021/.gitignore new file mode 100644 index 0000000..1d790d6 --- /dev/null +++ b/previous-2021/.gitignore @@ -0,0 +1,28 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ +/node_modules/ + +# misc +/.env* +/.pnp* +/.sass-cache +/.eslintcache +/connect.lock +/coverage/ +/libpeerconnection.log +/npm-debug.log* +/testem.log +/yarn-error.log + +# ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try + +.DS_Store diff --git a/previous-2021/.prettierignore b/previous-2021/.prettierignore new file mode 100644 index 0000000..9221655 --- /dev/null +++ b/previous-2021/.prettierignore @@ -0,0 +1,21 @@ +# unconventional js +/blueprints/*/files/ +/vendor/ + +# compiled output +/dist/ +/tmp/ + +# dependencies +/bower_components/ +/node_modules/ + +# misc +/coverage/ +!.* +.eslintcache + +# ember-try +/.node_modules.ember-try/ +/bower.json.ember-try +/package.json.ember-try diff --git a/.prettierrc.js b/previous-2021/.prettierrc.js similarity index 100% rename from .prettierrc.js rename to previous-2021/.prettierrc.js diff --git a/.template-lintrc.js b/previous-2021/.template-lintrc.js similarity index 100% rename from .template-lintrc.js rename to previous-2021/.template-lintrc.js diff --git a/.travis.yml b/previous-2021/.travis.yml similarity index 100% rename from .travis.yml rename to previous-2021/.travis.yml diff --git a/.watchmanconfig b/previous-2021/.watchmanconfig similarity index 100% rename from .watchmanconfig rename to previous-2021/.watchmanconfig diff --git a/previous-2021/README.md b/previous-2021/README.md new file mode 100644 index 0000000..0d961ea --- /dev/null +++ b/previous-2021/README.md @@ -0,0 +1,56 @@ +# you-are-a-tree + +This README outlines the details of collaborating on this Ember application. +A short introduction of this app could easily go here. + +## Prerequisites + +You will need the following things properly installed on your computer. + +* [Git](https://git-scm.com/) +* [Node.js](https://nodejs.org/) (with npm) +* [Ember CLI](https://ember-cli.com/) +* [Google Chrome](https://google.com/chrome/) + +## Installation + +* `git clone ` this repository +* `cd you-are-a-tree` +* `npm install` + +## Running / Development + +* `ember serve` +* Visit your app at [http://localhost:4200](http://localhost:4200). +* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests). + +### Code Generators + +Make use of the many generators for code, try `ember help generate` for more details + +### Running Tests + +* `ember test` +* `ember test --server` + +### Linting + +* `npm run lint` +* `npm run lint:fix` + +### Building + +* `ember build` (development) +* `ember build --environment production` (production) + +### Deploying + +Specify what it takes to deploy your app. + +## Further Reading / Useful Links + +* [ember.js](https://emberjs.com/) +* [ember-cli](https://ember-cli.com/) +* Development Browser Extensions + * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) + * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) diff --git a/app/app.js b/previous-2021/app/app.js similarity index 100% rename from app/app.js rename to previous-2021/app/app.js diff --git a/app/components/.gitkeep b/previous-2021/app/components/.gitkeep similarity index 100% rename from app/components/.gitkeep rename to previous-2021/app/components/.gitkeep diff --git a/app/components/action.hbs b/previous-2021/app/components/action.hbs similarity index 100% rename from app/components/action.hbs rename to previous-2021/app/components/action.hbs diff --git a/app/components/actions.hbs b/previous-2021/app/components/actions.hbs similarity index 100% rename from app/components/actions.hbs rename to previous-2021/app/components/actions.hbs diff --git a/app/components/actions.js b/previous-2021/app/components/actions.js similarity index 100% rename from app/components/actions.js rename to previous-2021/app/components/actions.js diff --git a/app/components/bar-chart.hbs b/previous-2021/app/components/bar-chart.hbs similarity index 100% rename from app/components/bar-chart.hbs rename to previous-2021/app/components/bar-chart.hbs diff --git a/app/components/bar-chart.js b/previous-2021/app/components/bar-chart.js similarity index 100% rename from app/components/bar-chart.js rename to previous-2021/app/components/bar-chart.js diff --git a/app/components/game-interface.hbs b/previous-2021/app/components/game-interface.hbs similarity index 100% rename from app/components/game-interface.hbs rename to previous-2021/app/components/game-interface.hbs diff --git a/app/components/game-interface.js b/previous-2021/app/components/game-interface.js similarity index 100% rename from app/components/game-interface.js rename to previous-2021/app/components/game-interface.js diff --git a/app/components/sidebar.hbs b/previous-2021/app/components/sidebar.hbs similarity index 100% rename from app/components/sidebar.hbs rename to previous-2021/app/components/sidebar.hbs diff --git a/app/components/sidebar.js b/previous-2021/app/components/sidebar.js similarity index 100% rename from app/components/sidebar.js rename to previous-2021/app/components/sidebar.js diff --git a/app/components/start-screen.hbs b/previous-2021/app/components/start-screen.hbs similarity index 100% rename from app/components/start-screen.hbs rename to previous-2021/app/components/start-screen.hbs diff --git a/app/components/start-screen.js b/previous-2021/app/components/start-screen.js similarity index 100% rename from app/components/start-screen.js rename to previous-2021/app/components/start-screen.js diff --git a/app/components/thermometer.hbs b/previous-2021/app/components/thermometer.hbs similarity index 100% rename from app/components/thermometer.hbs rename to previous-2021/app/components/thermometer.hbs diff --git a/app/components/thermometer.js b/previous-2021/app/components/thermometer.js similarity index 100% rename from app/components/thermometer.js rename to previous-2021/app/components/thermometer.js diff --git a/app/components/tree.hbs b/previous-2021/app/components/tree.hbs similarity index 100% rename from app/components/tree.hbs rename to previous-2021/app/components/tree.hbs diff --git a/app/components/tree.js b/previous-2021/app/components/tree.js similarity index 100% rename from app/components/tree.js rename to previous-2021/app/components/tree.js diff --git a/app/components/weather-bg.hbs b/previous-2021/app/components/weather-bg.hbs similarity index 100% rename from app/components/weather-bg.hbs rename to previous-2021/app/components/weather-bg.hbs diff --git a/app/controllers/.gitkeep b/previous-2021/app/controllers/.gitkeep similarity index 100% rename from app/controllers/.gitkeep rename to previous-2021/app/controllers/.gitkeep diff --git a/app/helpers/.gitkeep b/previous-2021/app/helpers/.gitkeep similarity index 100% rename from app/helpers/.gitkeep rename to previous-2021/app/helpers/.gitkeep diff --git a/app/helpers/format-float.js b/previous-2021/app/helpers/format-float.js similarity index 100% rename from app/helpers/format-float.js rename to previous-2021/app/helpers/format-float.js diff --git a/app/index.html b/previous-2021/app/index.html similarity index 100% rename from app/index.html rename to previous-2021/app/index.html diff --git a/app/models/.gitkeep b/previous-2021/app/models/.gitkeep similarity index 100% rename from app/models/.gitkeep rename to previous-2021/app/models/.gitkeep diff --git a/app/router.js b/previous-2021/app/router.js similarity index 100% rename from app/router.js rename to previous-2021/app/router.js diff --git a/app/routes/.gitkeep b/previous-2021/app/routes/.gitkeep similarity index 100% rename from app/routes/.gitkeep rename to previous-2021/app/routes/.gitkeep diff --git a/app/routes/about.js b/previous-2021/app/routes/about.js similarity index 100% rename from app/routes/about.js rename to previous-2021/app/routes/about.js diff --git a/app/routes/index.js b/previous-2021/app/routes/index.js similarity index 100% rename from app/routes/index.js rename to previous-2021/app/routes/index.js diff --git a/app/routes/intro.js b/previous-2021/app/routes/intro.js similarity index 100% rename from app/routes/intro.js rename to previous-2021/app/routes/intro.js diff --git a/app/routes/play.js b/previous-2021/app/routes/play.js similarity index 100% rename from app/routes/play.js rename to previous-2021/app/routes/play.js diff --git a/app/services/game.js b/previous-2021/app/services/game.js similarity index 100% rename from app/services/game.js rename to previous-2021/app/services/game.js diff --git a/app/services/locale.js b/previous-2021/app/services/locale.js similarity index 100% rename from app/services/locale.js rename to previous-2021/app/services/locale.js diff --git a/app/services/tree.js b/previous-2021/app/services/tree.js similarity index 100% rename from app/services/tree.js rename to previous-2021/app/services/tree.js diff --git a/app/styles/actions.css b/previous-2021/app/styles/actions.css similarity index 100% rename from app/styles/actions.css rename to previous-2021/app/styles/actions.css diff --git a/app/styles/app.css b/previous-2021/app/styles/app.css similarity index 100% rename from app/styles/app.css rename to previous-2021/app/styles/app.css diff --git a/app/styles/game-interface.css b/previous-2021/app/styles/game-interface.css similarity index 100% rename from app/styles/game-interface.css rename to previous-2021/app/styles/game-interface.css diff --git a/app/styles/start-screen.css b/previous-2021/app/styles/start-screen.css similarity index 100% rename from app/styles/start-screen.css rename to previous-2021/app/styles/start-screen.css diff --git a/app/styles/thermometer.css b/previous-2021/app/styles/thermometer.css similarity index 100% rename from app/styles/thermometer.css rename to previous-2021/app/styles/thermometer.css diff --git a/app/styles/vars.css b/previous-2021/app/styles/vars.css similarity index 100% rename from app/styles/vars.css rename to previous-2021/app/styles/vars.css diff --git a/app/styles/weather-bg.css b/previous-2021/app/styles/weather-bg.css similarity index 100% rename from app/styles/weather-bg.css rename to previous-2021/app/styles/weather-bg.css diff --git a/app/templates/about.hbs b/previous-2021/app/templates/about.hbs similarity index 100% rename from app/templates/about.hbs rename to previous-2021/app/templates/about.hbs diff --git a/app/templates/application.hbs b/previous-2021/app/templates/application.hbs similarity index 100% rename from app/templates/application.hbs rename to previous-2021/app/templates/application.hbs diff --git a/app/templates/intro.hbs b/previous-2021/app/templates/intro.hbs similarity index 100% rename from app/templates/intro.hbs rename to previous-2021/app/templates/intro.hbs diff --git a/app/templates/play.hbs b/previous-2021/app/templates/play.hbs similarity index 100% rename from app/templates/play.hbs rename to previous-2021/app/templates/play.hbs diff --git a/app/templates/play/one.hbs b/previous-2021/app/templates/play/one.hbs similarity index 100% rename from app/templates/play/one.hbs rename to previous-2021/app/templates/play/one.hbs diff --git a/app/templates/play/two.hbs b/previous-2021/app/templates/play/two.hbs similarity index 100% rename from app/templates/play/two.hbs rename to previous-2021/app/templates/play/two.hbs diff --git a/app/utils/random.js b/previous-2021/app/utils/random.js similarity index 100% rename from app/utils/random.js rename to previous-2021/app/utils/random.js diff --git a/config/ember-cli-update.json b/previous-2021/config/ember-cli-update.json similarity index 100% rename from config/ember-cli-update.json rename to previous-2021/config/ember-cli-update.json diff --git a/config/environment.js b/previous-2021/config/environment.js similarity index 100% rename from config/environment.js rename to previous-2021/config/environment.js diff --git a/config/optional-features.json b/previous-2021/config/optional-features.json similarity index 100% rename from config/optional-features.json rename to previous-2021/config/optional-features.json diff --git a/config/targets.js b/previous-2021/config/targets.js similarity index 100% rename from config/targets.js rename to previous-2021/config/targets.js diff --git a/ember-cli-build.js b/previous-2021/ember-cli-build.js similarity index 100% rename from ember-cli-build.js rename to previous-2021/ember-cli-build.js diff --git a/package-lock.json b/previous-2021/package-lock.json similarity index 100% rename from package-lock.json rename to previous-2021/package-lock.json diff --git a/previous-2021/package.json b/previous-2021/package.json new file mode 100644 index 0000000..e05059b --- /dev/null +++ b/previous-2021/package.json @@ -0,0 +1,80 @@ +{ + "name": "you-are-a-tree", + "version": "0.0.0", + "private": true, + "description": "Small description for you-are-a-tree goes here", + "repository": "", + "license": "MIT", + "author": "", + "directories": { + "doc": "doc", + "test": "tests" + }, + "scripts": { + "build": "ember build --environment=production", + "lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'", + "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix", + "lint:hbs": "ember-template-lint .", + "lint:hbs:fix": "ember-template-lint . --fix", + "lint:js": "eslint . --cache", + "lint:js:fix": "eslint . --fix", + "start": "ember serve --port=4300", + "server": "ember server", + "test": "npm-run-all lint test:*", + "test:ember": "ember test" + }, + "devDependencies": { + "@ember/optional-features": "^2.0.0", + "@ember/render-modifiers": "^1.0.2", + "@ember/test-helpers": "^2.2.5", + "@glimmer/component": "^1.0.4", + "@glimmer/tracking": "^1.0.4", + "babel-eslint": "^10.1.0", + "broccoli-asset-rev": "^3.0.0", + "ember-auto-import": "^1.11.2", + "ember-cli": "~3.26.0", + "ember-cli-app-version": "^5.0.0", + "ember-cli-babel": "^7.26.3", + "ember-cli-dependency-checker": "^3.2.0", + "ember-cli-htmlbars": "^5.7.1", + "ember-cli-inject-live-reload": "^2.0.2", + "ember-cli-postcss": "^7.0.2", + "ember-cli-sri": "^2.1.1", + "ember-cli-terser": "^4.0.1", + "ember-concurrency": "^2.1.2", + "ember-d3": "^0.5.1", + "ember-data": "~3.26.0", + "ember-export-application-global": "^2.0.1", + "ember-fetch": "^8.0.4", + "ember-load-initializers": "^2.1.2", + "ember-maybe-import-regenerator": "^0.1.6", + "ember-modal-dialog": "^3.0.3", + "ember-page-title": "^6.2.1", + "ember-qunit": "^5.1.4", + "ember-resolver": "^8.0.2", + "ember-source": "~3.26.1", + "ember-template-lint": "^3.2.0", + "ember-truth-helpers": "^3.0.0", + "ember-welcome-page": "^4.0.0", + "eslint": "^7.23.0", + "eslint-config-prettier": "^8.1.0", + "eslint-plugin-ember": "^10.3.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.3.1", + "game": "^1.0.3", + "loader.js": "^4.7.0", + "npm-run-all": "^4.1.5", + "postcss-cssnext": "^3.1.0", + "postcss-import": "^14.0.2", + "prettier": "^2.2.1", + "qunit": "^2.14.1", + "qunit-dom": "^1.6.0", + "service": "^0.1.4" + }, + "engines": { + "node": "10.* || >= 12" + }, + "ember": { + "edition": "octane" + } +} diff --git a/public/_redirects b/previous-2021/public/_redirects similarity index 100% rename from public/_redirects rename to previous-2021/public/_redirects diff --git a/public/robots.txt b/previous-2021/public/robots.txt similarity index 100% rename from public/robots.txt rename to previous-2021/public/robots.txt diff --git a/testem.js b/previous-2021/testem.js similarity index 100% rename from testem.js rename to previous-2021/testem.js diff --git a/tests/helpers/.gitkeep b/previous-2021/tests/helpers/.gitkeep similarity index 100% rename from tests/helpers/.gitkeep rename to previous-2021/tests/helpers/.gitkeep diff --git a/tests/index.html b/previous-2021/tests/index.html similarity index 100% rename from tests/index.html rename to previous-2021/tests/index.html diff --git a/tests/integration/.gitkeep b/previous-2021/tests/integration/.gitkeep similarity index 100% rename from tests/integration/.gitkeep rename to previous-2021/tests/integration/.gitkeep diff --git a/tests/integration/components/action-test.js b/previous-2021/tests/integration/components/action-test.js similarity index 100% rename from tests/integration/components/action-test.js rename to previous-2021/tests/integration/components/action-test.js diff --git a/tests/integration/components/actions-test.js b/previous-2021/tests/integration/components/actions-test.js similarity index 100% rename from tests/integration/components/actions-test.js rename to previous-2021/tests/integration/components/actions-test.js diff --git a/tests/integration/components/bar-chart-test.js b/previous-2021/tests/integration/components/bar-chart-test.js similarity index 100% rename from tests/integration/components/bar-chart-test.js rename to previous-2021/tests/integration/components/bar-chart-test.js diff --git a/tests/integration/components/game-interface-test.js b/previous-2021/tests/integration/components/game-interface-test.js similarity index 100% rename from tests/integration/components/game-interface-test.js rename to previous-2021/tests/integration/components/game-interface-test.js diff --git a/tests/integration/components/sidebar-test.js b/previous-2021/tests/integration/components/sidebar-test.js similarity index 100% rename from tests/integration/components/sidebar-test.js rename to previous-2021/tests/integration/components/sidebar-test.js diff --git a/tests/integration/components/start-screen-test.js b/previous-2021/tests/integration/components/start-screen-test.js similarity index 100% rename from tests/integration/components/start-screen-test.js rename to previous-2021/tests/integration/components/start-screen-test.js diff --git a/tests/integration/components/thermometer-test.js b/previous-2021/tests/integration/components/thermometer-test.js similarity index 100% rename from tests/integration/components/thermometer-test.js rename to previous-2021/tests/integration/components/thermometer-test.js diff --git a/tests/integration/components/tree-test.js b/previous-2021/tests/integration/components/tree-test.js similarity index 100% rename from tests/integration/components/tree-test.js rename to previous-2021/tests/integration/components/tree-test.js diff --git a/tests/integration/components/weather-bg-test.js b/previous-2021/tests/integration/components/weather-bg-test.js similarity index 100% rename from tests/integration/components/weather-bg-test.js rename to previous-2021/tests/integration/components/weather-bg-test.js diff --git a/tests/integration/helpers/format-float-test.js b/previous-2021/tests/integration/helpers/format-float-test.js similarity index 100% rename from tests/integration/helpers/format-float-test.js rename to previous-2021/tests/integration/helpers/format-float-test.js diff --git a/tests/test-helper.js b/previous-2021/tests/test-helper.js similarity index 100% rename from tests/test-helper.js rename to previous-2021/tests/test-helper.js diff --git a/tests/unit/.gitkeep b/previous-2021/tests/unit/.gitkeep similarity index 100% rename from tests/unit/.gitkeep rename to previous-2021/tests/unit/.gitkeep diff --git a/tests/unit/controllers/play-test.js b/previous-2021/tests/unit/controllers/play-test.js similarity index 100% rename from tests/unit/controllers/play-test.js rename to previous-2021/tests/unit/controllers/play-test.js diff --git a/tests/unit/routes/about-test.js b/previous-2021/tests/unit/routes/about-test.js similarity index 100% rename from tests/unit/routes/about-test.js rename to previous-2021/tests/unit/routes/about-test.js diff --git a/tests/unit/routes/intro-test.js b/previous-2021/tests/unit/routes/intro-test.js similarity index 100% rename from tests/unit/routes/intro-test.js rename to previous-2021/tests/unit/routes/intro-test.js diff --git a/tests/unit/routes/play-test.js b/previous-2021/tests/unit/routes/play-test.js similarity index 100% rename from tests/unit/routes/play-test.js rename to previous-2021/tests/unit/routes/play-test.js diff --git a/tests/unit/routes/play/one-test.js b/previous-2021/tests/unit/routes/play/one-test.js similarity index 100% rename from tests/unit/routes/play/one-test.js rename to previous-2021/tests/unit/routes/play/one-test.js diff --git a/tests/unit/routes/play/two-test.js b/previous-2021/tests/unit/routes/play/two-test.js similarity index 100% rename from tests/unit/routes/play/two-test.js rename to previous-2021/tests/unit/routes/play/two-test.js diff --git a/tests/unit/services/game-test.js b/previous-2021/tests/unit/services/game-test.js similarity index 100% rename from tests/unit/services/game-test.js rename to previous-2021/tests/unit/services/game-test.js diff --git a/tests/unit/services/locale-test.js b/previous-2021/tests/unit/services/locale-test.js similarity index 100% rename from tests/unit/services/locale-test.js rename to previous-2021/tests/unit/services/locale-test.js diff --git a/tests/unit/services/tree-test.js b/previous-2021/tests/unit/services/tree-test.js similarity index 100% rename from tests/unit/services/tree-test.js rename to previous-2021/tests/unit/services/tree-test.js diff --git a/tests/unit/utils/random-test.js b/previous-2021/tests/unit/utils/random-test.js similarity index 100% rename from tests/unit/utils/random-test.js rename to previous-2021/tests/unit/utils/random-test.js diff --git a/vendor/.gitkeep b/previous-2021/vendor/.gitkeep similarity index 100% rename from vendor/.gitkeep rename to previous-2021/vendor/.gitkeep diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..f273cc5 --- /dev/null +++ b/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/demo.spec.ts b/src/demo.spec.ts new file mode 100644 index 0000000..e07cbbd --- /dev/null +++ b/src/demo.spec.ts @@ -0,0 +1,7 @@ +import { describe, it, expect } from 'vitest'; + +describe('sum test', () => { + it('adds 1 + 2 to equal 3', () => { + expect(1 + 2).toBe(3); + }); +}); diff --git a/src/lib/Controls.svelte b/src/lib/Controls.svelte new file mode 100644 index 0000000..dd2cc19 --- /dev/null +++ b/src/lib/Controls.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/src/lib/DebugClock.svelte b/src/lib/DebugClock.svelte new file mode 100644 index 0000000..5862113 --- /dev/null +++ b/src/lib/DebugClock.svelte @@ -0,0 +1,13 @@ + + +

Clock

+
+
Year
+
{$gameState.clock.cycle}
+
Season
+
{getSeason($gameState.clock.position)}
+
pos: {$gameState.clock.position}
+
diff --git a/src/lib/DebugTree.svelte b/src/lib/DebugTree.svelte new file mode 100644 index 0000000..fbfb4d5 --- /dev/null +++ b/src/lib/DebugTree.svelte @@ -0,0 +1,13 @@ + + +

Tree

+
+
HP
+
{$gameState.php}
+
Height
+
{$gameState.tree.height}
+
Girth
+
{$gameState.tree.leafiness}
+
diff --git a/src/lib/assets/favicon.svg b/src/lib/assets/favicon.svg new file mode 100644 index 0000000..cc5dc66 --- /dev/null +++ b/src/lib/assets/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/src/lib/core/clock.ts b/src/lib/core/clock.ts new file mode 100644 index 0000000..6ca736e --- /dev/null +++ b/src/lib/core/clock.ts @@ -0,0 +1,30 @@ +import type { GameClock } from './types'; + +const CYCLE_DURATION_MS = 1000 * 60 * 1; // 4 minutes per cycle (year) + +// getSeason returns the current season based on the position in the cycle +// 0 is winter solstice, 0.25 is spring equinox, 0.5 is summer solstice, 0.75 is autumn equinox +export const getSeason = (pos: number): string => { + if (pos < 0.25) return 'winter'; + if (pos < 0.5) return 'spring'; + if (pos < 0.75) return 'summer'; + return 'autumn'; +}; + +export const getDay = (pos: number, daysPerCycle = 120): number => + Math.floor(pos * daysPerCycle) + 1; + +// Advancing the clock +export function advanceClock( + clock: GameClock, + elapsedMs: number, + speedMultiplier: number +): GameClock { + const tickSize = (elapsedMs / CYCLE_DURATION_MS) * speedMultiplier; + const newPosition = clock.position + tickSize; + + if (newPosition >= 1.0) { + return { cycle: clock.cycle + 1, position: newPosition - 1.0 }; + } + return { ...clock, position: newPosition }; +} diff --git a/src/lib/core/engine.ts b/src/lib/core/engine.ts new file mode 100644 index 0000000..1b060ee --- /dev/null +++ b/src/lib/core/engine.ts @@ -0,0 +1,101 @@ +import { advanceClock } from './clock'; +import { gameState } from './gamestate'; +import { type GameState, initialGameState } from './types'; + +const TICK_MS = 1000; // how often ticks happen, in milliseconds + +function advanceGameState(state: GameState, elapsed: number, speed: number): GameState { + // For now, just advance the clock; tree doesn't do anything yet + const clock = advanceClock(state.clock, elapsed, speed); + // earn HP + // check for events + return { + ...state, + clock + }; +} + +// TODO: flesh this out +type PlayerAction = { + amount: number; + target: 'height' | 'girth' | 'leafiness'; +}; + +// TODO: take in action +function applyPlayerAction(state: GameState): GameState { + // For now, just a stub; no actual actions implemented yet + return state; +} + +// engine.ts — completely framework-agnostic +class GameEngine { + private state: GameState; + private listeners: Set<(state: GameState) => void> = new Set(); + private animFrame: number | null = null; + private lastTick: number = 0; + speed: number = 1; // speed multiplier for time-based events + + constructor() { + this.state = initialGameState; + } + + private startClock() { + if (this.animFrame !== null) return; // already running — no double-start + this.lastTick = Date.now(); + this.animFrame = requestAnimationFrame(() => this.tick()); + } + + private stopClock() { + if (this.animFrame === null) return; + cancelAnimationFrame(this.animFrame); + this.animFrame = null; + } + + private tick() { + const now = Date.now(); + const elapsed = now - this.lastTick; + + if (elapsed >= TICK_MS && this.state.status === 'running') { + this.lastTick = now; + // const prevPosition = this.state.clock.position; + this.state = advanceGameState(this.state, elapsed, this.speed); + // processEvents(prevPosition, this.state.clock.position, this.state); + this.notify(); + } + + this.animFrame = requestAnimationFrame(() => this.tick()); + } + + private notify() { + gameState.set(this.state); // update the Svelte store with the new state + this.listeners.forEach((fn) => { + fn(this.state); + }); + } + + // React (or Svelte) subscribes here + subscribe(fn: (state: GameState) => void) { + this.listeners.add(fn); + return () => this.listeners.delete(fn); + } + + // PLAYER ACTIONS + start() { + this.state.status = 'running'; + this.startClock(); + this.notify(); + } + + pause() { + this.state.status = 'paused'; + this.stopClock(); + this.notify(); + } + spendHP(action: PlayerAction) { + console.log('Player action:', action); + this.state = applyPlayerAction(this.state); + this.notify(); + } +} + +export const engine = new GameEngine(); diff --git a/src/lib/core/gamestate.ts b/src/lib/core/gamestate.ts new file mode 100644 index 0000000..d85b022 --- /dev/null +++ b/src/lib/core/gamestate.ts @@ -0,0 +1,4 @@ +import { writable } from 'svelte/store'; +import { type GameState, initialGameState } from './types'; + +export const gameState = writable(initialGameState); diff --git a/src/lib/core/types.ts b/src/lib/core/types.ts new file mode 100644 index 0000000..785efd9 --- /dev/null +++ b/src/lib/core/types.ts @@ -0,0 +1,34 @@ +export type GameClock = { + cycle: number; // which year we're on (integer, ever-increasing) + position: number; // 0.0–1.0, position within current cycle +}; + +type TreeState = { height: number; girth: number; leafiness: number }; + +type PendingEvent = { + type: string; +}; + +export type GameState = { + status: 'paused' | 'running' | 'awaiting_input'; + php: number; // photosynthesis energy + clock: GameClock; + tree: TreeState; + pendingEvent: PendingEvent | undefined; +}; + +// DEFAULTS + +const DEFAULT_CLOCK: GameClock = { + cycle: 1, + position: 0.25 // start at beginning of spring +}; +export const initialGameState: GameState = { + status: 'awaiting_input', + clock: DEFAULT_CLOCK, + php: 0, + tree: { height: 1, girth: 1, leafiness: 1 }, + pendingEvent: { + type: 'start_game' + } +}; diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..856f2b6 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..9cebde5 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,11 @@ + + + + + + +{@render children()} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..e842f8e --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,21 @@ + + +

You are a tree

+ + + + +{#if $gameState.status === 'awaiting_input'} + +{/if} + + diff --git a/src/routes/page.svelte.spec.ts b/src/routes/page.svelte.spec.ts new file mode 100644 index 0000000..d54f00a --- /dev/null +++ b/src/routes/page.svelte.spec.ts @@ -0,0 +1,13 @@ +import { page } from 'vitest/browser'; +import { describe, expect, it } from 'vitest'; +import { render } from 'vitest-browser-svelte'; +import Page from './+page.svelte'; + +describe('/+page.svelte', () => { + it('should render h1', async () => { + render(Page); + + const heading = page.getByRole('heading', { level: 1 }); + await expect.element(heading).toBeInTheDocument(); + }); +}); diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..10c4eeb --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-auto'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://svelte.dev/docs/kit/adapters for more information about adapters. + adapter: adapter() + } +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2c2ed3c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..282a635 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,35 @@ +import { defineConfig } from 'vitest/config'; +import { playwright } from '@vitest/browser-playwright'; +import { sveltekit } from '@sveltejs/kit/vite'; + +export default defineConfig({ + plugins: [sveltekit()], + test: { + expect: { requireAssertions: true }, + projects: [ + { + extends: './vite.config.ts', + test: { + name: 'client', + browser: { + enabled: true, + provider: playwright(), + instances: [{ browser: 'chromium', headless: true }] + }, + include: ['src/**/*.svelte.{test,spec}.{js,ts}'], + exclude: ['src/lib/server/**'] + } + }, + + { + extends: './vite.config.ts', + test: { + name: 'server', + environment: 'node', + include: ['src/**/*.{test,spec}.{js,ts}'], + exclude: ['src/**/*.svelte.{test,spec}.{js,ts}'] + } + } + ] + } +});