diff --git a/angular.json b/angular.json index 71d0ec42..7e3ac347 100644 --- a/angular.json +++ b/angular.json @@ -44,7 +44,7 @@ "with": "src/environments/environment.prod.ts" } ], - "optimization": true, + "optimization": false, "outputHashing": "all", "sourceMap": false, "aot": true, @@ -62,9 +62,15 @@ "maximumWarning": "6kb" } ] + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true } }, - "defaultConfiguration": "" + "defaultConfiguration": "development" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", @@ -78,7 +84,12 @@ "production": { "buildTarget": "samples:build:production" } - } + , + "development": { + "buildTarget": "samples:build:development" + } + }, + "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json index 22e04cb1..f7d4e860 100644 --- a/e2e/tsconfig.e2e.json +++ b/e2e/tsconfig.e2e.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "../out-tsc/app", "module": "commonjs", - "target": "es5", + "target": "es2025", "types": ["jasmine", "jasminewd2", "node"] } } diff --git a/logprops.md b/logprops.md new file mode 100644 index 00000000..89a1bc8c --- /dev/null +++ b/logprops.md @@ -0,0 +1,239 @@ +# CSS Logical Properties Migration Plan + +Generated: March 10, 2026 + +This document outlines the plan to migrate from physical CSS properties to logical properties for better internationalization and RTL support. + +## Background + +Physical CSS properties (e.g., `margin-left`, `width`, `height`, `top`) are tied to the physical dimensions of the screen. Logical properties (e.g., `margin-inline-start`, `inline-size`, `block-size`, `inset-block-start`) adapt to the writing mode (LTR/RTL, horizontal/vertical). + +--- + +## Found Issues Summary + +| Category | Count | +| -------------------------------- | ----- | +| Margin (physical) | ~25 | +| Padding (physical) | ~15 | +| Border (physical) | ~30 | +| Position (top/left/right/bottom) | ~15 | +| Width/Height (physical) | ~100 | +| Float | 1 | +| Text-align (physical) | ~12 | +| Vertical-align | 3 | + +--- + +## Detailed Findings + +### 1. Margin Properties (Physical) + +**Current:** `margin-top`, `margin-bottom`, `margin-left`, `margin-right` + +**Replace with:** `margin-block-start`, `margin-block-end`, `margin-inline-start`, `margin-inline-end` + +**Files affected:** + +- `src/app/mqtt/power-meter/dialog/power-meter-dialog.component.css:33` → `margin-inline-start` +- `src/styles.css:175` → `margin-block-end` +- `src/app/signal-forms-experiment/signal-forms-experiment.component.css:3,59` → `margin-block-start` / `margin-inline-start` +- `src/app/rvt/template/template.component.css:22` → `margin-inline-start` +- `src/app/rvt/reactive/reactive.component.css:22` → `margin-inline-start` +- `projects/slido/src/styles.css:28,81` → `margin-inline-start` / `margin-block-start` +- `projects/wire-it-editor/src/app/wireits/wireits.component.css:2` → `margin-block-start` +- And ~15 more instances + +--- + +### 2. Padding Properties (Physical) + +**Current:** `padding-top`, `padding-bottom`, `padding-left`, `padding-right` + +**Replace with:** `padding-block-start`, `padding-block-end`, `padding-inline-start`, `padding-inline-end` + +**Files affected:** + +- `projects/slido/src/app/slide/slide.component.css:137,141` → `padding-block-end` +- `projects/slido/src/styles.css:85,99` → `padding-inline-start` +- `src/app/rijks/artists/artists.component.css:7,8` → `padding-inline-start/end` +- `src/app/rijks/art-detail/art-detail.component.css:13,14` → `padding-inline-start/end` +- `projects/api-boundries/src/app/b-relation-list/relation/relation.component.css:43` → `padding-inline-start` +- `projects/api-boundries/src/app/relation-list/relation/relation.component.css:40` → `padding-inline-start` +- And ~8 more instances + +--- + +### 3. Border Properties (Physical) + +**Current:** `border-top`, `border-bottom`, `border-left`, `border-right`, `border-top-width`, etc. + +**Replace with:** `border-block-start`, `border-block-end`, `border-inline-start`, `border-inline-end` + +**Files affected:** + +- `projects/slido/src/styles.css:43,54,98,99` → `border-inline-start` +- `src/app/grid-calender/day-cell/day-cell.component.css:34-45` → `border-inline-start/end`, `border-block-start/end` +- `src/app/grid-calender/month/month.component.css:35-77` → Multiple border-inline/block usage +- And ~20 more instances + +--- + +### 4. Position Properties (Physical) + +**Current:** `top`, `bottom`, `left`, `right` + +**Replace with:** `inset-block-start`, `inset-block-end`, `inset-inline-start`, `inset-inline-end` + +**Files affected:** + +- `src/styles.css:149,150` → `inset-block-start: 0`, `inset-inline-start: 0` +- `src/app/signal-forms-experiment/signal-forms-experiment.component.css:137,138` → `inset-inline-end`, `inset-block-start` +- `projects/slido/src/app/slide/slide.component.css:149` → `inset-block-start` +- `projects/slido/src/app/present/present.component.css:29,30` → `inset-inline-end`, `inset-block-end` +- `src/app/stepper/stepper.component.css:34` → `inset-inline-start` +- `src/app/stepper/step/step.component.css:18,19` → `inset-block-start`, `inset-inline-end` +- `src/app/card/card.component.css:8,9` → `inset-block-start: 0`, `inset-inline-start: 0` +- And ~8 more instances + +--- + +### 5. Width/Height (Physical) + +**Current:** `width`, `height`, `min-width`, `min-height`, `max-width`, `max-height` + +**Replace with:** `inline-size`, `block-size`, `min-inline-size`, `min-block-size`, `max-inline-size`, `max-block-size` + +**Files affected:** + +- `src/app/grid-play/grid-play.component.css:13,14` → `inline-size`, `block-size` +- `src/styles.css:151,152` → `inline-size: 100vw`, `block-size: 100vh` +- `src/app/signal-forms-experiment/signal-forms-experiment.component.css:4,10,125,126,147` → `max-inline-size`, `inline-size`, `block-size` +- `projects/slido/src/app/slide/slide.component.css:12,13,88,89,107,116,117,120,121,128,129,135,145,161,184,195` → Multiple +- `projects/slipnslide/src/styles.css:6,27,34-37,100` → `block-size`, `inline-size` +- And ~80 more instances + +--- + +### 6. Float (Physical) + +**Current:** `float: left`, `float: right` + +**Replace with:** `float: inline-start`, `float: inline-end` + +**Files affected:** + +- `src/app/cells/cell-raw/cell-raw.component.css:28` → `float: inline-start` + +--- + +### 7. Text-align (Physical) + +**Current:** `text-align: left`, `text-align: right`, `text-align: center` + +**Replace with:** `text-align: start`, `text-align: end` + +**Note:** `center` is valid in both physical and logical, but prefer logical flow-relative when possible. + +**Files affected:** + +- `src/app/blogs/blogs.component.css:53` → `text-align: start` +- `src/app/crud-stuff/user-row/user-row.component.css:18` → `text-align: start` +- `src/app/indexdb/edit-record/edit-record.component.css:18` → `text-align: end` +- `projects/slido/src/app/slide/slide.component.css:104,152` → `text-align: start/end` +- And ~8 more instances + +--- + +### 8. Vertical-align + +**Current:** `vertical-align: baseline`, `vertical-align: top` + +**Replace with:** `vertical-align: auto` (for baseline), or use `align-content` with flexbox/grid + +**Files affected:** + +- `src/styles.css:170,205` → Review flex/grid alternatives +- `projects/slipnslide/src/styles.css:56,77` → Review flex/grid alternatives + +--- + +## Migration Priority + +### Phase 1: High Impact (Core Layout) + +1. **Width/Height** → `inline-size`/`block-size` (~100 occurrences) +2. **Position** → `inset-*` (~15 occurrences) +3. **Margin** → `margin-block-*`/`margin-inline-*` (~25 occurrences) + +### Phase 2: Border & Padding + +4. **Padding** → `padding-block-*`/`padding-inline-*` (~15 occurrences) +5. **Border** → `border-block-*`/`border-inline-*` (~30 occurrences) + +### Phase 3: Fine-tuning + +6. **Text-align** → `start`/`end` (~12 occurrences) +7. **Float** → `inline-start`/`inline-end` (1 occurrence) +8. **Vertical-align** → Review flex/grid alternatives (3 occurrences) + +--- + +## Recommended Approach + +1. **Use a linter rule** - Add `property-horizontal-Physical` ESLint rule to catch new violations +2. **Incremental migration** - Focus on one component at a time +3. **Test RTL** - Verify layouts work in both LTR and RTL modes after changes +4. **Use CSS custom properties** - Where appropriate, define logical spacing tokens + +--- + +## Example Transformations + +### Before (Physical) + +```css +.card { + margin-left: 1rem; + margin-top: 0.5rem; + width: 100%; + height: 50px; + border-left: 2px solid red; + top: 0; + left: 0; + float: left; + text-align: right; +} +``` + +### After (Logical) + +```css +.card { + margin-inline-start: 1rem; + margin-block-start: 0.5rem; + inline-size: 100%; + block-size: 50px; + border-inline-start: 2px solid red; + inset-block-start: 0; + inset-inline-start: 0; + float: inline-start; + text-align: end; +} +``` + +--- + +## Estimated Effort + +- **Files to modify:** ~50 +- **Estimated changes:** ~250 properties +- **Time estimate:** 4-6 hours for full migration + +--- + +## Tools & Resources + +- [MDN: CSS Logical Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) +- [CSS Triggers](https://csstriggers.com/) - Check if property changes trigger layout +- Browser support: All modern browsers support logical properties (IE11 has no support) diff --git a/package.json b/package.json index b51e52e2..83966ffc 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,6 @@ "articles/*.md" ], "clean": false - }, "build.lib.let": { "command": "ng build @se-ng/let --configuration production", @@ -230,19 +229,19 @@ } }, "dependencies": { - "@angular/animations": "22.0.0-next.2", - "@angular/aria": "22.0.0-next.0", - "@angular/cdk": "22.0.0-next.0", - "@angular/common": "22.0.0-next.2", - "@angular/compiler": "22.0.0-next.2", - "@angular/core": "22.0.0-next.2", - "@angular/elements": "22.0.0-next.2", - "@angular/forms": "22.0.0-next.2", - "@angular/platform-browser": "22.0.0-next.2", - "@angular/platform-browser-dynamic": "22.0.0-next.2", - "@angular/platform-server": "22.0.0-next.2", - "@angular/router": "22.0.0-next.2", - "@angular/ssr": "22.0.0-next.1", + "@angular/animations": "22.0.0-next.4", + "@angular/aria": "22.0.0-next.1", + "@angular/cdk": "22.0.0-next.1", + "@angular/common": "22.0.0-next.4", + "@angular/compiler": "22.0.0-next.4", + "@angular/core": "22.0.0-next.4", + "@angular/elements": "22.0.0-next.4", + "@angular/forms": "22.0.0-next.4", + "@angular/platform-browser": "22.0.0-next.4", + "@angular/platform-browser-dynamic": "22.0.0-next.4", + "@angular/platform-server": "22.0.0-next.4", + "@angular/router": "22.0.0-next.4", + "@angular/ssr": "22.0.0-next.2", "@faker-js/faker": "10.3.0", "@fortawesome/fontawesome-free": "7.2.0", "@fortawesome/fontawesome-svg-core": "7.2.0", @@ -255,13 +254,13 @@ "bson": "7.2.0", "chance": "1.1.13", "colorjs.io": "0.6.1", - "core-js": "3.48.0", + "core-js": "3.49.0", "express": "5.2.1", "front-matter": "4.0.2", "highlight.js": "11.11.1", - "hono": "^4.12.7", + "hono": "^4.12.8", "idb-keyval": "6.2.2", - "jsdom": "28.1.0", + "jsdom": "29.0.0", "marked": "17.0.4", "marked-highlight": "2.2.3", "messagepack": "1.1.12", @@ -283,14 +282,14 @@ "asciidoctor.js": {} }, "devDependencies": { - "@angular-devkit/build-angular": "22.0.0-next.1", - "@angular-eslint/builder": "21.3.0", - "@angular-eslint/eslint-plugin": "^21.3.0", - "@angular-eslint/template-parser": "21.3.0", - "@angular/build": "22.0.0-next.1", - "@angular/cli": "22.0.0-next.1", - "@angular/compiler-cli": "22.0.0-next.2", - "@angular/language-service": "22.0.0-next.2", + "@angular-devkit/build-angular": "22.0.0-next.2", + "@angular-eslint/builder": "21.3.1", + "@angular-eslint/eslint-plugin": "^21.3.1", + "@angular-eslint/template-parser": "21.3.1", + "@angular/build": "22.0.0-next.2", + "@angular/cli": "22.0.0-next.2", + "@angular/compiler-cli": "22.0.0-next.4", + "@angular/language-service": "22.0.0-next.4", "@eslint/js": "^9.39.2", "@npmcli/package-json": "7.0.5", "@playwright/test": "1.58.2", @@ -302,11 +301,11 @@ "@types/msgpack-lite": "0.1.12", "@types/node": "24.10.1", "@types/wicg-file-system-access": "2023.10.7", - "@typescript-eslint/eslint-plugin": "8.57.0", - "@typescript-eslint/parser": "8.57.0", + "@typescript-eslint/eslint-plugin": "8.57.1", + "@typescript-eslint/parser": "8.57.1", "@vitest/coverage-v8": "4.1.0", "@web/test-runner": "0.20.2", - "angular-eslint": "21.3.0", + "angular-eslint": "21.3.1", "eslint": "^9.39.2", "eslint-plugin-simple-import-sort": "12.1.1", "eslint-plugin-unused-imports": "4.4.1", @@ -318,7 +317,7 @@ "ts-node": "10.9.2", "tsc-watch": "7.2.0", "typescript": "~5.9.3", - "typescript-eslint": "8.57.0", + "typescript-eslint": "8.57.1", "wireit": "0.14.12", "yargs": "18.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6974b818..43c0f27f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,44 +9,44 @@ importers: .: dependencies: '@angular/animations': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) '@angular/aria': - specifier: 22.0.0-next.0 - version: 22.0.0-next.0(@angular/cdk@22.0.0-next.0(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + specifier: 22.0.0-next.1 + version: 22.0.0-next.1(@angular/cdk@22.0.0-next.1(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) '@angular/cdk': - specifier: 22.0.0-next.0 - version: 22.0.0-next.0(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: 22.0.0-next.1 + version: 22.0.0-next.1(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) '@angular/common': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2 + specifier: 22.0.0-next.4 + version: 22.0.0-next.4 '@angular/core': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) '@angular/elements': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) '@angular/forms': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) '@angular/platform-browser': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) '@angular/platform-browser-dynamic': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))) '@angular/platform-server': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) '@angular/ssr': - specifier: 22.0.0-next.1 - version: 22.0.0-next.1(96fec6be6d0f7e9eab47b3f9f854d9a9) + specifier: 22.0.0-next.2 + version: 22.0.0-next.2(f93605c2441543804e2c011df626dcc1) '@faker-js/faker': specifier: 10.3.0 version: 10.3.0 @@ -64,7 +64,7 @@ importers: version: 7.2.0 '@hono/node-server': specifier: 1.19.11 - version: 1.19.11(hono@4.12.7) + version: 1.19.11(hono@4.12.8) '@ngneat/falso': specifier: 8.0.2 version: 8.0.2 @@ -84,8 +84,8 @@ importers: specifier: 0.6.1 version: 0.6.1 core-js: - specifier: 3.48.0 - version: 3.48.0 + specifier: 3.49.0 + version: 3.49.0 express: specifier: 5.2.1 version: 5.2.1 @@ -96,14 +96,14 @@ importers: specifier: 11.11.1 version: 11.11.1 hono: - specifier: ^4.12.7 - version: 4.12.7 + specifier: ^4.12.8 + version: 4.12.8 idb-keyval: specifier: 6.2.2 version: 6.2.2 jsdom: - specifier: 28.1.0 - version: 28.1.0 + specifier: 29.0.0 + version: 29.0.0 marked: specifier: 17.0.4 version: 17.0.4 @@ -148,35 +148,35 @@ importers: version: 2.8.1 vitest: specifier: 4.1.0 - version: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + version: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) yaml: specifier: 2.8.2 version: 2.8.2 devDependencies: '@angular-devkit/build-angular': - specifier: 22.0.0-next.1 - version: 22.0.0-next.1(b58f28129b55da2054db6022b2fb7678) + specifier: 22.0.0-next.2 + version: 22.0.0-next.2(1d89ba7fcb7784d2422393ab9b59433f) '@angular-eslint/builder': - specifier: 21.3.0 - version: 21.3.0(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: 21.3.1 + version: 21.3.1(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@angular-eslint/eslint-plugin': - specifier: ^21.3.0 - version: 21.3.0(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: ^21.3.1 + version: 21.3.1(@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@angular-eslint/template-parser': - specifier: 21.3.0 - version: 21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: 21.3.1 + version: 21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@angular/build': - specifier: 22.0.0-next.1 - version: 22.0.0-next.1(fb4e45d759185d3e5b1efa3e6e7773f3) + specifier: 22.0.0-next.2 + version: 22.0.0-next.2(1c08417c58e603e54e28921a55c48eb9) '@angular/cli': - specifier: 22.0.0-next.1 - version: 22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0) - '@angular/compiler-cli': specifier: 22.0.0-next.2 - version: 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) + version: 22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0) + '@angular/compiler-cli': + specifier: 22.0.0-next.4 + version: 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3) '@angular/language-service': - specifier: 22.0.0-next.2 - version: 22.0.0-next.2 + specifier: 22.0.0-next.4 + version: 22.0.0-next.4 '@eslint/js': specifier: ^9.39.2 version: 9.39.3 @@ -211,20 +211,20 @@ importers: specifier: 2023.10.7 version: 2023.10.7 '@typescript-eslint/eslint-plugin': - specifier: 8.57.0 - version: 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.57.1 + version: 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.57.0 - version: 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.57.1 + version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: 4.1.0 - version: 4.1.0(vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + version: 4.1.0(vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2)) '@web/test-runner': specifier: 0.20.2 version: 0.20.2 angular-eslint: - specifier: 21.3.0 - version: 21.3.0(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript-eslint@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(typescript@5.9.3) + specifier: 21.3.1 + version: 21.3.1(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript-eslint@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(typescript@5.9.3) eslint: specifier: ^9.39.2 version: 9.39.3(jiti@2.6.1) @@ -233,7 +233,7 @@ importers: version: 12.1.1(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-unused-imports: specifier: 4.4.1 - version: 4.4.1(@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1)) + version: 4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1)) json5: specifier: 2.2.3 version: 2.2.3 @@ -242,7 +242,7 @@ importers: version: 2.0.2 ng-packagr: specifier: 22.0.0-next.0 - version: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + version: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) prettier: specifier: 3.8.1 version: 3.8.1 @@ -259,8 +259,8 @@ importers: specifier: ~5.9.3 version: 5.9.3 typescript-eslint: - specifier: 8.57.0 - version: 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.57.1 + version: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) wireit: specifier: 0.14.12 version: 0.14.12 @@ -270,63 +270,60 @@ importers: packages: - '@acemir/cssom@0.9.31': - resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} - - '@algolia/abtesting@1.15.1': - resolution: {integrity: sha512-2yuIC48rUuHGhU1U5qJ9kJHaxYpJ0jpDHJVI5ekOxSMYXlH4+HP+pA31G820lsAznfmu2nzDV7n5RO44zIY1zw==} + '@algolia/abtesting@1.15.2': + resolution: {integrity: sha512-rF7vRVE61E0QORw8e2NNdnttcl3jmFMWS9B4hhdga12COe+lMa26bQLfcBn/Nbp9/AF/8gXdaRCPsVns3CnjsA==} engines: {node: '>= 14.0.0'} - '@algolia/client-abtesting@5.49.1': - resolution: {integrity: sha512-h6M7HzPin+45/l09q0r2dYmocSSt2MMGOOk5c4O5K/bBBlEwf1BKfN6z+iX4b8WXcQQhf7rgQwC52kBZJt/ZZw==} + '@algolia/client-abtesting@5.49.2': + resolution: {integrity: sha512-XyvKCm0RRmovMI/ChaAVjTwpZhXdbgt3iZofK914HeEHLqD1MUFFVLz7M0+Ou7F56UkHXwRbpHwb9xBDNopprQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.49.1': - resolution: {integrity: sha512-048T9/Z8OeLmTk8h76QUqaNFp7Rq2VgS2Zm6Y2tNMYGQ1uNuzePY/udB5l5krlXll7ZGflyCjFvRiOtlPZpE9g==} + '@algolia/client-analytics@5.49.2': + resolution: {integrity: sha512-jq/3qvtmj3NijZlhq7A1B0Cl41GfaBpjJxcwukGsYds6aMSCWrEAJ9pUqw/C9B3hAmILYKl7Ljz3N9SFvekD3Q==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.49.1': - resolution: {integrity: sha512-vp5/a9ikqvf3mn9QvHN8PRekn8hW34aV9eX+O0J5mKPZXeA6Pd5OQEh2ZWf7gJY6yyfTlLp5LMFzQUAU+Fpqpg==} + '@algolia/client-common@5.49.2': + resolution: {integrity: sha512-bn0biLequn3epobCfjUqCxlIlurLr4RHu7RaE4trgN+RDcUq6HCVC3/yqq1hwbNYpVtulnTOJzcaxYlSr1fnuw==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.49.1': - resolution: {integrity: sha512-B6N7PgkvYrul3bntTz/l6uXnhQ2bvP+M7NqTcayh681tSqPaA5cJCUBp/vrP7vpPRpej4Eeyx2qz5p0tE/2N2g==} + '@algolia/client-insights@5.49.2': + resolution: {integrity: sha512-z14wfFs1T3eeYbCArC8pvntAWsPo9f6hnUGoj8IoRUJTwgJiiySECkm8bmmV47/x0oGHfsVn3kBdjMX0yq0sNA==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.49.1': - resolution: {integrity: sha512-v+4DN+lkYfBd01Hbnb9ZrCHe7l+mvihyx218INRX/kaCXROIWUDIT1cs3urQxfE7kXBFnLsqYeOflQALv/gA5w==} + '@algolia/client-personalization@5.49.2': + resolution: {integrity: sha512-GpRf7yuuAX93+Qt0JGEJZwgtL0MFdjFO9n7dn8s2pA9mTjzl0Sc5+uTk1VPbIAuf7xhCP9Mve+URGb6J+EYxgA==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.49.1': - resolution: {integrity: sha512-Un11cab6ZCv0W+Jiak8UktGIqoa4+gSNgEZNfG8m8eTsXGqwIEr370H3Rqwj87zeNSlFpH2BslMXJ/cLNS1qtg==} + '@algolia/client-query-suggestions@5.49.2': + resolution: {integrity: sha512-HZwApmNkp0DiAjZcLYdQLddcG4Agb88OkojiAHGgcm5DVXobT5uSZ9lmyrbw/tmQBJwgu2CNw4zTyXoIB7YbPA==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.49.1': - resolution: {integrity: sha512-Nt9hri7nbOo0RipAsGjIssHkpLMHHN/P7QqENywAq5TLsoYDzUyJGny8FEiD/9KJUxtGH8blGpMedilI6kK3rA==} + '@algolia/client-search@5.49.2': + resolution: {integrity: sha512-y1IOpG6OSmTpGg/CT0YBb/EAhR2nsC18QWp9Jy8HO9iGySpcwaTvs5kHa17daP3BMTwWyaX9/1tDTDQshZzXdg==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.49.1': - resolution: {integrity: sha512-b5hUXwDqje0Y4CpU6VL481DXgPgxpTD5sYMnfQTHKgUispGnaCLCm2/T9WbJo1YNUbX3iHtYDArp804eD6CmRQ==} + '@algolia/ingestion@1.49.2': + resolution: {integrity: sha512-YYJRjaZ2bqk923HxE4um7j/Cm3/xoSkF2HC2ZweOF8cXL3sqnlndSUYmCaxHFjNPWLaSHk2IfssX6J/tdKTULw==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.49.1': - resolution: {integrity: sha512-bvrXwZ0WsL3rN6Q4m4QqxsXFCo6WAew7sAdrpMQMK4Efn4/W920r9ptOuckejOSSvyLr9pAWgC5rsHhR2FYuYw==} + '@algolia/monitoring@1.49.2': + resolution: {integrity: sha512-9WgH+Dha39EQQyGKCHlGYnxW/7W19DIrEbCEbnzwAMpGAv1yTWCHMPXHxYa+LcL3eCp2V/5idD1zHNlIKmHRHg==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.49.1': - resolution: {integrity: sha512-h2yz3AGeGkQwNgbLmoe3bxYs8fac4An1CprKTypYyTU/k3Q+9FbIvJ8aS1DoBKaTjSRZVoyQS7SZQio6GaHbZw==} + '@algolia/recommend@5.49.2': + resolution: {integrity: sha512-K7Gp5u+JtVYgaVpBxF5rGiM+Ia8SsMdcAJMTDV93rwh00DKNllC19o1g+PwrDjDvyXNrnTEbofzbTs2GLfFyKA==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.49.1': - resolution: {integrity: sha512-2UPyRuUR/qpqSqH8mxFV5uBZWEpxhGPHLlx9Xf6OVxr79XO2ctzZQAhsmTZ6X22x+N8MBWpB9UEky7YU2HGFgA==} + '@algolia/requester-browser-xhr@5.49.2': + resolution: {integrity: sha512-3UhYCcWX6fbtN8ABcxZlhaQEwXFh3CsFtARyyadQShHMPe3mJV9Wel4FpJTa+seugRkbezFz0tt6aPTZSYTBuA==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.49.1': - resolution: {integrity: sha512-N+xlE4lN+wpuT+4vhNEwPVlrfN+DWAZmSX9SYhbz986Oq8AMsqdntOqUyiOXVxYsQtfLwmiej24vbvJGYv1Qtw==} + '@algolia/requester-fetch@5.49.2': + resolution: {integrity: sha512-G94VKSGbsr+WjsDDOBe5QDQ82QYgxvpxRGJfCHZBnYKYsy/jv9qGIDb93biza+LJWizQBUtDj7bZzp3QZyzhPQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.49.1': - resolution: {integrity: sha512-zA5bkUOB5PPtTr182DJmajCiizHp0rCJQ0Chf96zNFvkdESKYlDeYA3tQ7r2oyHbu/8DiohAQ5PZ85edctzbXA==} + '@algolia/requester-node-http@5.49.2': + resolution: {integrity: sha512-UuihBGHafG/ENsrcTGAn5rsOffrCIRuHMOsD85fZGLEY92ate+BMTUqxz60dv5zerh8ZumN4bRm8eW2z9L11jA==} engines: {node: '>= 14.0.0'} '@ampproject/remapping@2.3.0': @@ -338,13 +335,13 @@ packages: engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/architect@0.2200.0-next.1': - resolution: {integrity: sha512-RVIPARkITnDXZsk3lAqAJMNI7X9QGZ0EfnnjT6pcW82MobX4jY207E5V4kDk/6WM3IU5F9latVwwjOKWZ+LlMg==} + '@angular-devkit/architect@0.2200.0-next.2': + resolution: {integrity: sha512-4f9EiZ4mBZKGsL+P/tjThYPcUdSUvo3CwfjKzR5dYjQNhXWdzRHrfvk6boJldqcCNVFqIR3X+H+v/pauTEddMw==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/build-angular@22.0.0-next.1': - resolution: {integrity: sha512-w8nMLpE4qqHW7Y9v0B+sl3DMHoNgZw03yBqvfVX0BdKcGBG5nBIoLduIgn3gHoqnK5qE6s2L+3g9+5NuJNUcsg==} + '@angular-devkit/build-angular@22.0.0-next.2': + resolution: {integrity: sha512-NuCzNY+oFz1eqCo5BmY42iRiXUnf2Do4fFGy6zA4UslFsJ4bfOGxixZYhe/pFlQFFulsdkzIVkGE9cVdK5iANA==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: '@angular/compiler-cli': ^22.0.0-next.0 @@ -353,7 +350,7 @@ packages: '@angular/platform-browser': ^22.0.0-next.0 '@angular/platform-server': ^22.0.0-next.0 '@angular/service-worker': ^22.0.0-next.0 - '@angular/ssr': ^22.0.0-next.1 + '@angular/ssr': ^22.0.0-next.2 browser-sync: ^3.0.2 karma: ^6.3.0 ng-packagr: ^22.0.0-next.0 @@ -381,8 +378,8 @@ packages: tailwindcss: optional: true - '@angular-devkit/build-webpack@0.2200.0-next.1': - resolution: {integrity: sha512-sTHcGYmtGveHIHvF2CEO/9eYym1kWWHXLwlfg6OE12HsXrtVe7tR5IMlhozqZAjocLkhzMn2C8VcHpBSqFpxYg==} + '@angular-devkit/build-webpack@0.2200.0-next.2': + resolution: {integrity: sha512-0fq7BNafzb5pqwMBsJe9KkhlhKmAnqPHVHn+ANsOCdPcWN2Av4ZOl9Y5eX+UKwIjMyNQ9OB6K43MxUkUaHRxfQ==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: webpack: ^5.30.0 @@ -397,8 +394,8 @@ packages: chokidar: optional: true - '@angular-devkit/core@22.0.0-next.1': - resolution: {integrity: sha512-3ANorrFj0dIQDWJnaHKvI2H/7zYeNjD+LEJy/pjDgxqaldGuLFFiMZgUd1C/Fkt+oCee8cgWJIU+NUNZy7SLPw==} + '@angular-devkit/core@22.0.0-next.2': + resolution: {integrity: sha512-GIp2PqabUoqvN7acPqNScqi3X+YSJaV+KkAl2p5J/h0dncAUQsbnyY00zolFiCXhH9XZZGO4HaS94hGvoPJYSA==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^5.0.0 @@ -410,68 +407,68 @@ packages: resolution: {integrity: sha512-CWoamHaasAHMjHcYqxbj0tMnoXxdGotcAz2SpiuWtH28Lnf5xfbTaJn/lwdMP8Wdh4tgA+uYh2l45A5auCwmkw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular-devkit/schematics@22.0.0-next.1': - resolution: {integrity: sha512-6unx5K3XP9Fd9yPldl01EMd4qBnxk6WoxB/B5QPssIWM4BdJk4mR2ae9IOe41hxJPQc+svnSBjPbg22VzdPuMw==} + '@angular-devkit/schematics@22.0.0-next.2': + resolution: {integrity: sha512-ZpNi0vzk8VrrXScnDhE/nIdwGkEwlQdONawXfX4stsBOS5hwrKNsoMR1chU198Ucfm5dL4fF5VEXMUGmseCS5w==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular-eslint/builder@21.3.0': - resolution: {integrity: sha512-26QUUouei52biUFAlJSrWNAU9tuF2miKwd8uHdxWwCF31xz+OxC5+NfudWvt1AFaYow7gWueX1QX3rNNtSPDrg==} + '@angular-eslint/builder@21.3.1': + resolution: {integrity: sha512-1f1Lyp5e7OH6txiV224HaY3G1uRCj91OSKq7hT2Vw9NRw6zWFc1anBpDeLVjpL9ptUxzUGIQR5jEV54hOPayoQ==} peerDependencies: '@angular/cli': '>= 21.0.0 < 22.0.0' eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '*' - '@angular-eslint/bundled-angular-compiler@21.3.0': - resolution: {integrity: sha512-l521I24J9gJxyMbRkrM24Tc7W8J8BP+TDAmVs2nT8+lXbS3kg8QpWBRtd+hNUgq6o+vt+lKBkytnEfu8OiqeRg==} + '@angular-eslint/bundled-angular-compiler@21.3.1': + resolution: {integrity: sha512-jjbnJPUXQeQBJ8RM+ahlbt4GH2emVN8JvG3AhFbPci1FrqXi9cOOfkbwLmvpoyTli4LF8gy7g4ctFqnlRgqryw==} - '@angular-eslint/eslint-plugin-template@21.3.0': - resolution: {integrity: sha512-lVixd/KypPWgA/5/pUOhJV9MTcaHjYZEqyOi+IiLk+h+maGxn6/s6Ot+20n+XGS85zAgOY+qUw6EEQ11hoojIQ==} + '@angular-eslint/eslint-plugin-template@21.3.1': + resolution: {integrity: sha512-ndPWJodkcEOu2PVUxlUwyz4D2u3r9KO7veWmStVNOLeNrICJA+nQvrz2BWCu0l48rO0K5ezsy0JFcQDVwE/5mw==} peerDependencies: - '@angular-eslint/template-parser': 21.3.0 + '@angular-eslint/template-parser': 21.3.1 '@typescript-eslint/types': ^7.11.0 || ^8.0.0 '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '*' - '@angular-eslint/eslint-plugin@21.3.0': - resolution: {integrity: sha512-Whf/AUUBekOlfSJRS78m76YGrBQAZ3waXE7oOdlW5xEQvn8jBDN9EGuNnjg/syZzvzjK4ZpYC4g1XYXrc+fQIg==} + '@angular-eslint/eslint-plugin@21.3.1': + resolution: {integrity: sha512-08NNTxwawRLTWPLl8dg1BnXMwimx93y4wMEwx2aWQpJbIt4pmNvwJzd+NgoD/Ag2VdLS/gOMadhJH5fgaYKsPQ==} peerDependencies: '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '*' - '@angular-eslint/schematics@21.3.0': - resolution: {integrity: sha512-8deU/zVY9f8k8kAQQ9PL130ox2VlrZw3fMxgsPNAY5tjQ0xk0J2YVSszYHhcqdMGG1J01IsxIjvQaJ4pFfEmMw==} + '@angular-eslint/schematics@21.3.1': + resolution: {integrity: sha512-1U2u4ZsZvwT30aXRLsIJf6tULIiioo9BtASNsldpYecU3/m/1+F61lCYG79qt7YWbif9KABPYZlFTJUFGN8HWA==} peerDependencies: '@angular/cli': '>= 21.0.0 < 22.0.0' - '@angular-eslint/template-parser@21.3.0': - resolution: {integrity: sha512-ysyou1zAY6M6rSZNdIcYKGd4nk6TCapamyFNB3ivmTlVZ0O35TS9o/rJ0aUttuHgDp+Ysgs3ql+LA746PXgCyQ==} + '@angular-eslint/template-parser@21.3.1': + resolution: {integrity: sha512-moERVCTekQKOvR8RMuEOtWSO3VS1qrzA3keI1dPto/JVB8Nqp9w3R5ZpEoXHzh4zgEryosxmPgdi6UczJe2ouQ==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '*' - '@angular-eslint/utils@21.3.0': - resolution: {integrity: sha512-oNigH6w3l+owTMboj/uFG0tHOy43uH8BpQRtBOQL1/s2+5in/BJ2Fjobv3SyizxTgeJ1FhRefbkT8GmVjK7jAA==} + '@angular-eslint/utils@21.3.1': + resolution: {integrity: sha512-Q3SGA1/36phZhmsp1mYrKzp/jcmqofRr861MYn46FaWIKSYXBYRzl+H3FIJKBu5CE36Bggu6hbNpwGPuUp+MCg==} peerDependencies: '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '*' - '@angular/animations@22.0.0-next.2': - resolution: {integrity: sha512-AET2hF1P4kDU1q77eVm7ylsHsSHM87OhDk9ydKZObS64mhQLdKNcHLaHoreUtqr2mJVZV0U9KOuKWmevo5Oi6g==} + '@angular/animations@22.0.0-next.4': + resolution: {integrity: sha512-lQ54Qmqy4MtFSxOuPGv6s+q/lwSFWYOSA0UAxBx3ow+LdINdrIfaV9WO+brJjN1TvKAZ+0pb5CrXFaYMtApMkw==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/core': 22.0.0-next.2 + '@angular/core': 22.0.0-next.4 - '@angular/aria@22.0.0-next.0': - resolution: {integrity: sha512-U9RzdqsLP678Qts7agfoBSNdVllvlkCC6FldRvuFDHESfT/7aIQMKQLorI7GnQAiMgxg+s3HCVZuwQdUkhOc4Q==} + '@angular/aria@22.0.0-next.1': + resolution: {integrity: sha512-DeTuoOOp7ZmIGMW9GimY2Du51rCXOs+BhJ4pVAoKP0RWMfJxr0reXaxF4gWPlxFW/ReRAf+d0hwK+jFh/YOXeA==} peerDependencies: - '@angular/cdk': 22.0.0-next.0 + '@angular/cdk': 22.0.0-next.1 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/build@22.0.0-next.1': - resolution: {integrity: sha512-XA/kbYiHtb01ysQ91QVYr4ocIHY2CWPvSEio11xNes11RfbiU0kgx3Rz+PSJu90wCEq0vy04CP7c/qlswzAfgQ==} + '@angular/build@22.0.0-next.2': + resolution: {integrity: sha512-67k6VJva6shimicdnK6ur3pBCmSi77FEq+eJrs9jzlqkbaJAzmAiotCYNMGhceyKlCpZAvG6Sw5k/YWZCDqdnw==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: '@angular/compiler': ^22.0.0-next.0 @@ -481,7 +478,7 @@ packages: '@angular/platform-browser': ^22.0.0-next.0 '@angular/platform-server': ^22.0.0-next.0 '@angular/service-worker': ^22.0.0-next.0 - '@angular/ssr': ^22.0.0-next.1 + '@angular/ssr': ^22.0.0-next.2 karma: ^6.4.0 less: ^4.2.0 ng-packagr: ^22.0.0-next.0 @@ -516,46 +513,46 @@ packages: vitest: optional: true - '@angular/cdk@22.0.0-next.0': - resolution: {integrity: sha512-ca6pMpN9tAupIyr8LDaqpVlBN9beGL91unXH95pGfsngTCWcz7mh3IYVQ2CJ24e9O+2Lp/gtLYhvzOpIUpiV3A==} + '@angular/cdk@22.0.0-next.1': + resolution: {integrity: sha512-tSRpCd2udTRe/52fHBLaKmD+nVHtQKtVh5lJuhk1RPmdsCQqn+4wY8d96xS0qdx3Xk+0nTZmQl2LnIqCkPOpfw==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/cli@22.0.0-next.1': - resolution: {integrity: sha512-+1Ro2j4p8bZjoJK6/BBIV1rClpQwbnzXTgIiTEyb99geoJJpDgoNTO4uCFecuEuKUE/VdbAEfKDSqrNi040FdQ==} + '@angular/cli@22.0.0-next.2': + resolution: {integrity: sha512-JrIB0RODhgdWS6NUMn3wSPkUVMBIxuAnoeWEDtvylCrSMWULRYnnUVfMgMLvRYsJIEVmVeCfaiauHDQFivbGiQ==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular/common@22.0.0-next.2': - resolution: {integrity: sha512-AImYdvf6vyqsijaXY1xhMCS9/Mmb7RClMFqy40qRElNEmbVQMXpvysnwRIZsgd6ncrIfJq1x570q9vXH8LPYJw==} + '@angular/common@22.0.0-next.4': + resolution: {integrity: sha512-/NuxmFa+koz4yDHEdaUsPy0aojC4yWx0zuUmLE6xdkYrE9dADaIf+9TtjpO4N8iJ+a/glWrYcCtXrsRl8BYr3A==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/core': 22.0.0-next.2 + '@angular/core': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.0.0-next.2': - resolution: {integrity: sha512-DmqcjCstHmEDxS6bGqIBW6Tf+kfFKshoKgHzdEXIcCFPpxVbWVJCUNGSmO5XZl+T5UW/CiKmyEzckCSsee8KIw==} + '@angular/compiler-cli@22.0.0-next.4': + resolution: {integrity: sha512-GDAOSQ9CafQeHA3Qt1nbBROgoJEFwb0/MfnPhROkvAyf3sXf1YwOgSVPWZv9NyVNPTEzZv70baA7cMJIwHyW/A==} engines: {node: ^22.22.0 || >=24.13.1} hasBin: true peerDependencies: - '@angular/compiler': 22.0.0-next.2 + '@angular/compiler': 22.0.0-next.4 typescript: '>=5.9 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.0.0-next.2': - resolution: {integrity: sha512-XFz+V0HkXlG1Ca+cJK8W/KjdEFWqNCPeQ0fRbdJngWC2fawwF5STNj8eTS9u1j6PwySajzu4OEyxJeVrDZMjDg==} + '@angular/compiler@22.0.0-next.4': + resolution: {integrity: sha512-8cA8L9sztyL7HsnkOK/wzRSHiqxztddLZ0bLNqhm8seIk7NkO3zIlya8V7GMVYh9EmZfBRV/OkRioHhaX+4bQA==} engines: {node: ^22.22.0 || >=24.13.1} - '@angular/core@22.0.0-next.2': - resolution: {integrity: sha512-xUxPiftI6I7I7n/LQoNJzjFRvmeanbDmrJMAAq63NBL1tXlj+3XYTyT0jUkyCVytv+pMOpoQoafuWPuoZMpFvQ==} + '@angular/core@22.0.0-next.4': + resolution: {integrity: sha512-w/OAuBhFpVAIMHDMWteK13jdTXtuKu52+OmnSrhj2TSNxmc1aKYFEvP2ERKdEvVlV8Bfcsg5zL86A7QRmTMfew==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/compiler': 22.0.0-next.2 + '@angular/compiler': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -564,67 +561,67 @@ packages: zone.js: optional: true - '@angular/elements@22.0.0-next.2': - resolution: {integrity: sha512-lFt9qTCBWDei2agqPHIoSXwhG8r05NINYejPf05jL7P6oqhwaRQW4EOlWfCSC5WkyMemRk2FxitdXDpkCUwuQQ==} + '@angular/elements@22.0.0-next.4': + resolution: {integrity: sha512-czcNCMUWBq1auqXLedEs5JPim0erzR6KHef4INkzm1w/JZvbQ8N+qeBoXpUpYSMNtzEwraxGq3eks+PCz3dvrQ==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/core': 22.0.0-next.2 + '@angular/core': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/forms@22.0.0-next.2': - resolution: {integrity: sha512-O4UJqUCI1DnmKYwiVnHMD9n8frnI8wyVc2EizislY5MOW/6w1Z5G24mjA3FDI1OJ1y75eyOynFLi0CKa9uE9bA==} + '@angular/forms@22.0.0-next.4': + resolution: {integrity: sha512-uZ/KlPa0llrMuhBzeaSCN68XNbF8LLFZhkypkDmIJ7jFkb7HJzcWKklar9VSMZimpA0B3LG6kjSEtbzAg0sJ1g==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/common': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2 - '@angular/platform-browser': 22.0.0-next.2 + '@angular/common': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4 + '@angular/platform-browser': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/language-service@22.0.0-next.2': - resolution: {integrity: sha512-Ua/QD+ZBE3GukUHgfDN1NX9aa1xjPMwzSGhr5D6+0gCT77JOSPEnjfM4iISbnPKWTNwzHcfLCDR72w2YGkBsNQ==} + '@angular/language-service@22.0.0-next.4': + resolution: {integrity: sha512-eRakcY5WkF9MIgN1+NmJAZfw/jd6O/5hdHFBTl7LmL/vQFtoVYAg1ywA9/izFQ0oX4W3fQgQk4zYFa9SWY9sKw==} engines: {node: ^22.22.0 || >=24.13.1} - '@angular/platform-browser-dynamic@22.0.0-next.2': - resolution: {integrity: sha512-3fSoae4s3iWyHYV2UAtWw0mQ9fslpNp7OdeCwJ5Nym7i/8rVkgnkCVQOlKJEmcdEdW6jCBbcjJMEQEirKp/hXg==} + '@angular/platform-browser-dynamic@22.0.0-next.4': + resolution: {integrity: sha512-cO2aPZRFkHRxaEWUx3PXLgzS4JeeazFktSlfLow1SlidhNmyjbf7KXme1dA7Nvp3YE/mkKqVv1WnGES/n9VR2w==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/common': 22.0.0-next.2 - '@angular/compiler': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2 - '@angular/platform-browser': 22.0.0-next.2 + '@angular/common': 22.0.0-next.4 + '@angular/compiler': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4 + '@angular/platform-browser': 22.0.0-next.4 - '@angular/platform-browser@22.0.0-next.2': - resolution: {integrity: sha512-orxlHh3fY1YZJuCuMNfBLhHCKC4GAqeGNdMfSVM52imgFxf5oa4Ss2A6Rg6kqdK7LlSL1Z4/3WVU7IL3QBzXOQ==} + '@angular/platform-browser@22.0.0-next.4': + resolution: {integrity: sha512-f1w43eHST5DmRb95mp7X0F0GtnssNK9a04YrfeA0ZIh7M0E3lyyuCvFyL8fhigx2aOkMZR4TdRfZ/Ukk0OWaAg==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/animations': 22.0.0-next.2 - '@angular/common': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2 + '@angular/animations': 22.0.0-next.4 + '@angular/common': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.0.0-next.2': - resolution: {integrity: sha512-HHld8KrqMCGv/R+LWIfNMbJUyIcQOwOolJjW02tRVGs9dNyaRYLvX+h0R5cyJ1BbU3NWi+O3XxjZ3+ZQw+Vclg==} + '@angular/platform-server@22.0.0-next.4': + resolution: {integrity: sha512-U9dDIIx25MlgCN+I+z7+gZbG4pKG+VzQOiN2FPwl3iwqPW6tY4gNRISwQ3pZEmKw92z+HllV7+IwT4KpEifXJQ==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/common': 22.0.0-next.2 - '@angular/compiler': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2 - '@angular/platform-browser': 22.0.0-next.2 + '@angular/common': 22.0.0-next.4 + '@angular/compiler': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4 + '@angular/platform-browser': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.0.0-next.2': - resolution: {integrity: sha512-AMbWhr2F7TXbIu7bEAcjKJzY9JvYEVgVoQVN0eRY5f+yv2L5Hv9+UjUU7Gvn2cFrEEsHvmJ6apRXAO5gnt1pWA==} + '@angular/router@22.0.0-next.4': + resolution: {integrity: sha512-FCJSxTEmXo2Oku2t+sgxBmEyLXGMmbNRHbtQWaFJH0OXgaWktstP3uMw5vMBK4td0kgl975F97xY4eDr0RizQQ==} engines: {node: ^22.22.0 || >=24.13.1} peerDependencies: - '@angular/common': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2 - '@angular/platform-browser': 22.0.0-next.2 + '@angular/common': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4 + '@angular/platform-browser': 22.0.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ssr@22.0.0-next.1': - resolution: {integrity: sha512-ckVHepuaui9+YMk5PvASBO+zQ9eaui3obk/9GGB+lOSzHVt31aOobVaLLak/V1VO4mv5ba3iYidSUh/4dYmPRg==} + '@angular/ssr@22.0.0-next.2': + resolution: {integrity: sha512-O1AK/YMY+4f7rMAHnI2BFJLCancTDEq683A4N2wXo4brsfXgCwp5pygBBi/pHfI7lzgrEkXlbEsWRjBdEjiqEg==} peerDependencies: '@angular/common': ^22.0.0-next.0 '@angular/core': ^22.0.0-next.0 @@ -638,8 +635,9 @@ packages: resolution: {integrity: sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - '@asamuzakjp/dom-selector@6.8.1': - resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} + '@asamuzakjp/dom-selector@7.0.3': + resolution: {integrity: sha512-Q6mU0Z6bfj6YvnX2k9n0JxiIwrCFN59x/nWmYQnAqP000ruX/yV+5bp/GRcF5T8ncvfwJQ7fgfP74DlpKExILA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} @@ -1185,8 +1183,13 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.0': - resolution: {integrity: sha512-H4tuz2nhWgNKLt1inYpoVCfbJbMwX/lQKp3g69rrrIMIYlFD9+zTykOKhNR8uGrAmbS/kT9n6hTFkmDkxLgeTA==} + '@csstools/css-syntax-patches-for-csstree@1.1.1': + resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true '@csstools/css-tokenizer@4.0.0': resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} @@ -1617,12 +1620,12 @@ packages: cpu: [x64] os: [win32] - '@inquirer/ansi@2.0.3': - resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==} + '@inquirer/ansi@2.0.4': + resolution: {integrity: sha512-DpcZrQObd7S0R/U3bFdkcT5ebRwbTTC4D3tCc1vsJizmgPLxNJBo+AAFmrZwe8zk30P2QzgzGWZ3Q9uJwWuhIg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/checkbox@5.1.0': - resolution: {integrity: sha512-/HjF1LN0a1h4/OFsbGKHNDtWICFU/dqXCdym719HFTyJo9IG7Otr+ziGWc9S0iQuohRZllh+WprSgd5UW5Fw0g==} + '@inquirer/checkbox@5.1.2': + resolution: {integrity: sha512-PubpMPO2nJgMufkoB3P2wwxNXEMUXnBIKi/ACzDUYfaoPuM7gSTmuxJeMscoLVEsR4qqrCMf5p0SiYGWnVJ8kw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1630,8 +1633,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.0.8': - resolution: {integrity: sha512-Di6dgmiZ9xCSUxWUReWTqDtbhXCuG2MQm2xmgSAIruzQzBqNf49b8E07/vbCYY506kDe8BiwJbegXweG8M1klw==} + '@inquirer/confirm@6.0.10': + resolution: {integrity: sha512-tiNyA73pgpQ0FQ7axqtoLUe4GDYjNCDcVsbgcA5anvwg2z6i+suEngLKKJrWKJolT//GFPZHwN30binDIHgSgQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1639,8 +1642,8 @@ packages: '@types/node': optional: true - '@inquirer/core@11.1.5': - resolution: {integrity: sha512-QQPAX+lka8GyLcZ7u7Nb1h6q72iZ/oy0blilC3IB2nSt1Qqxp7akt94Jqhi/DzARuN3Eo9QwJRvtl4tmVe4T5A==} + '@inquirer/core@11.1.7': + resolution: {integrity: sha512-1BiBNDk9btIwYIzNZpkikIHXWeNzNncJePPqwDyVMhXhD1ebqbpn1mKGctpoqAbzywZfdG0O4tvmsGIcOevAPQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1648,8 +1651,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.0.8': - resolution: {integrity: sha512-sLcpbb9B3XqUEGrj1N66KwhDhEckzZ4nI/W6SvLXyBX8Wic3LDLENlWRvkOGpCPoserabe+MxQkpiMoI8irvyA==} + '@inquirer/editor@5.0.10': + resolution: {integrity: sha512-VJx4XyaKea7t8hEApTw5dxeIyMtWXre2OiyJcICCRZI4hkoHsMoCnl/KbUnJJExLbH9csLLHMVR144ZhFE1CwA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1657,8 +1660,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.0.8': - resolution: {integrity: sha512-QieW3F1prNw3j+hxO7/NKkG1pk3oz7pOB6+5Upwu3OIwADfPX0oZVppsqlL+Vl/uBHHDSOBY0BirLctLnXwGGg==} + '@inquirer/expand@5.0.10': + resolution: {integrity: sha512-fC0UHJPXsTRvY2fObiwuQYaAnHrp3aDqfwKUJSdfpgv18QUG054ezGbaRNStk/BKD5IPijeMKWej8VV8O5Q/eQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1666,8 +1669,8 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@2.0.3': - resolution: {integrity: sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==} + '@inquirer/external-editor@2.0.4': + resolution: {integrity: sha512-Prenuv9C1PHj2Itx0BcAOVBTonz02Hc2Nd2DbU67PdGUaqn0nPCnV34oDyyoaZHnmfRxkpuhh/u51ThkrO+RdA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1675,12 +1678,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@2.0.3': - resolution: {integrity: sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==} + '@inquirer/figures@2.0.4': + resolution: {integrity: sha512-eLBsjlS7rPS3WEhmOmh1znQ5IsQrxWzxWDxO51e4urv+iVrSnIHbq4zqJIOiyNdYLa+BVjwOtdetcQx1lWPpiQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/input@5.0.8': - resolution: {integrity: sha512-p0IJslw0AmedLEkOU+yrEX3Aj2RTpQq7ZOf8nc1DIhjzaxRWrrgeuE5Kyh39fVRgtcACaMXx/9WNo8+GjgBOfw==} + '@inquirer/input@5.0.10': + resolution: {integrity: sha512-nvZ6qEVeX/zVtZ1dY2hTGDQpVGD3R7MYPLODPgKO8Y+RAqxkrP3i/3NwF3fZpLdaMiNuK0z2NaYIx9tPwiSegQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1688,8 +1691,8 @@ packages: '@types/node': optional: true - '@inquirer/number@4.0.8': - resolution: {integrity: sha512-uGLiQah9A0F9UIvJBX52m0CnqtLaym0WpT9V4YZrjZ+YRDKZdwwoEPz06N6w8ChE2lrnsdyhY9sL+Y690Kh9gQ==} + '@inquirer/number@4.0.10': + resolution: {integrity: sha512-Ht8OQstxiS3APMGjHV0aYAjRAysidWdwurWEo2i8yI5xbhOBWqizT0+MU1S2GCcuhIBg+3SgWVjEoXgfhY+XaA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1697,8 +1700,8 @@ packages: '@types/node': optional: true - '@inquirer/password@5.0.8': - resolution: {integrity: sha512-zt1sF4lYLdvPqvmvHdmjOzuUUjuCQ897pdUCO8RbXMUDKXJTTyOQgtn23le+jwcb+MpHl3VAFvzIdxRAf6aPlA==} + '@inquirer/password@5.0.10': + resolution: {integrity: sha512-QbNyvIE8q2GTqKLYSsA8ATG+eETo+m31DSR0+AU7x3d2FhaTWzqQek80dj3JGTo743kQc6mhBR0erMjYw5jQ0A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1706,8 +1709,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.3.0': - resolution: {integrity: sha512-JAj66kjdH/F1+B7LCigjARbwstt3SNUOSzMdjpsvwJmzunK88gJeXmcm95L9nw1KynvFVuY4SzXh/3Y0lvtgSg==} + '@inquirer/prompts@8.3.2': + resolution: {integrity: sha512-yFroiSj2iiBFlm59amdTvAcQFvWS6ph5oKESls/uqPBect7rTU2GbjyZO2DqxMGuIwVA8z0P4K6ViPcd/cp+0w==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1715,8 +1718,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.2.4': - resolution: {integrity: sha512-fTuJ5Cq9W286isLxwj6GGyfTjx1Zdk4qppVEPexFuA6yioCCXS4V1zfKroQqw7QdbDPN73xs2DiIAlo55+kBqg==} + '@inquirer/rawlist@5.2.6': + resolution: {integrity: sha512-jfw0MLJ5TilNsa9zlJ6nmRM0ZFVZhhTICt4/6CU2Dv1ndY7l3sqqo1gIYZyMMDw0LvE1u1nzJNisfHEhJIxq5w==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1724,8 +1727,8 @@ packages: '@types/node': optional: true - '@inquirer/search@4.1.4': - resolution: {integrity: sha512-9yPTxq7LPmYjrGn3DRuaPuPbmC6u3fiWcsE9ggfLcdgO/ICHYgxq7mEy1yJ39brVvgXhtOtvDVjDh9slJxE4LQ==} + '@inquirer/search@4.1.6': + resolution: {integrity: sha512-3/6kTRae98hhDevENScy7cdFEuURnSpM3JbBNg8yfXLw88HgTOl+neUuy/l9W0No5NzGsLVydhBzTIxZP7yChQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1733,8 +1736,8 @@ packages: '@types/node': optional: true - '@inquirer/select@5.1.0': - resolution: {integrity: sha512-OyYbKnchS1u+zRe14LpYrN8S0wH1vD0p2yKISvSsJdH2TpI87fh4eZdWnpdbrGauCRWDph3NwxRmM4Pcm/hx1Q==} + '@inquirer/select@5.1.2': + resolution: {integrity: sha512-kTK8YIkHV+f02y7bWCh7E0u2/11lul5WepVTclr3UMBtBr05PgcZNWfMa7FY57ihpQFQH/spLMHTcr0rXy50tA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -1751,6 +1754,15 @@ packages: '@types/node': optional: true + '@inquirer/type@4.0.4': + resolution: {integrity: sha512-PamArxO3cFJZoOzspzo6cxVlLeIftyBsZw/S9bKY5DzxqJVZgjoj1oP8d0rskKtp7sZxBycsoer1g6UeJV1BBA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -1911,38 +1923,38 @@ packages: '@inquirer/prompts': '>= 3 < 9' listr2: 10.2.1 - '@lmdb/lmdb-darwin-arm64@3.5.1': - resolution: {integrity: sha512-tpfN4kKrrMpQ+If1l8bhmoNkECJi0iOu6AEdrTJvWVC+32sLxTARX5Rsu579mPImRP9YFWfWgeRQ5oav7zApQQ==} + '@lmdb/lmdb-darwin-arm64@3.5.2': + resolution: {integrity: sha512-ZTEuSwB3QHOA6Jal4bi0oxAV1MK3xtzS3oUMq5OK3HSXNN4A79f9dhieZA0hgvwOTaGzEWmTd8Fg9XSkBIhAWw==} cpu: [arm64] os: [darwin] - '@lmdb/lmdb-darwin-x64@3.5.1': - resolution: {integrity: sha512-+a2tTfc3rmWhLAolFUWRgJtpSuu+Fw/yjn4rF406NMxhfjbMuiOUTDRvRlMFV+DzyjkwnokisskHbCWkS3Ly5w==} + '@lmdb/lmdb-darwin-x64@3.5.2': + resolution: {integrity: sha512-Zs+mdB6gNqpPK6ybNbqFoSU+DCIdhE8tqeaAzRs+hNJt8V43PRvTVxu1UPBHwK2917FnQ4dL5/OIoqHDa+9Dpw==} cpu: [x64] os: [darwin] - '@lmdb/lmdb-linux-arm64@3.5.1': - resolution: {integrity: sha512-aoERa5B6ywXdyFeYGQ1gbQpkMkDbEo45qVoXE5QpIRavqjnyPwjOulMkmkypkmsbJ5z4Wi0TBztON8agCTG0Vg==} + '@lmdb/lmdb-linux-arm64@3.5.2': + resolution: {integrity: sha512-hT6JPw5hDCXzppBgpIFS/cQp4v2LqNMgd5nuo4U9H5/wnbMS7Prh0twu5IbDvzYZf2a/xPTXtTDRuUiFc39lEw==} cpu: [arm64] os: [linux] - '@lmdb/lmdb-linux-arm@3.5.1': - resolution: {integrity: sha512-0EgcE6reYr8InjD7V37EgXcYrloqpxVPINy3ig1MwDSbl6LF/vXTYRH9OE1Ti1D8YZnB35ZH9aTcdfSb5lql2A==} + '@lmdb/lmdb-linux-arm@3.5.2': + resolution: {integrity: sha512-GhdC4huGWDzcbZWfS+G3dW4/TopNUnO+/E7aVdfWIhslSs1FI2+sVo94040S9BPJ7lNpnf1zVxaBlLmqZpKhcw==} cpu: [arm] os: [linux] - '@lmdb/lmdb-linux-x64@3.5.1': - resolution: {integrity: sha512-SqNDY1+vpji7bh0sFH5wlWyFTOzjbDOl0/kB5RLLYDAFyd/uw3n7wyrmas3rYPpAW7z18lMOi1yKlTPv967E3g==} + '@lmdb/lmdb-linux-x64@3.5.2': + resolution: {integrity: sha512-aTBBxTQGdgKcqZD6ywIVCIbCIJ3fJ28OhzCxgl3zGQzzJwkDt5TSIuBtMt4oKZMgDSjuRBjtID9TOUvSRg8IQA==} cpu: [x64] os: [linux] - '@lmdb/lmdb-win32-arm64@3.5.1': - resolution: {integrity: sha512-50v0O1Lt37cwrmR9vWZK5hRW0Aw+KEmxJJ75fge/zIYdvNKB/0bSMSVR5Uc2OV9JhosIUyklOmrEvavwNJ8D6w==} + '@lmdb/lmdb-win32-arm64@3.5.2': + resolution: {integrity: sha512-mqfNN5zb3z3QnHEPaV4Zv5zd3BhlcL+uqPNF7kGRkmCaRHuh6T9N5g/4ZqOiNHNPWglv3g8Ut15XxCKZjf6jHw==} cpu: [arm64] os: [win32] - '@lmdb/lmdb-win32-x64@3.5.1': - resolution: {integrity: sha512-qwosvPyl+zpUlp3gRb7UcJ3H8S28XHCzkv0Y0EgQToXjQP91ZD67EHSCDmaLjtKhe+GVIW5om1KUpzVLA0l6pg==} + '@lmdb/lmdb-win32-x64@3.5.2': + resolution: {integrity: sha512-JhPxlA8sIxPIdS78e4LeNfTlkF+2I/r98jKXf90pf+yhMCzyLkphcvbnWv7YL8yckp32c1uKZ1vf/JqcSiplHg==} cpu: [x64] os: [win32] @@ -2104,8 +2116,8 @@ packages: '@ngneat/falso@8.0.2': resolution: {integrity: sha512-vhPtuoHoxE5JGWPSPBqEyTXcjI4MAn8GllR+Vs8FfpAQu2sQRd4PJc3e8kc9vdbdhYHx1C9HmbECgtGLK30z4w==} - '@ngtools/webpack@22.0.0-next.1': - resolution: {integrity: sha512-pZSgt7KgnER/WdQInbEvnClvEqBhezdu4MMydCtK9tIPAYpLnmTBw190f+qWHDkrQ1EhemVx3fn7zovFaCoZ2Q==} + '@ngtools/webpack@22.0.0-next.2': + resolution: {integrity: sha512-2LizJlHgAUpNNPYpbFWRZVqCRXlYDZ6g+52Ba03E8Z5KMixTyPgen1Brgjv7e8C2LOiUWqLYakVi6x9D0MEVsg==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: '@angular/compiler-cli': ^22.0.0-next.0 @@ -2309,103 +2321,103 @@ packages: engines: {node: '>=18'} hasBin: true - '@rolldown/binding-android-arm64@1.0.0-rc.7': - resolution: {integrity: sha512-/uadfNUaMLFFBGvcIOiq8NnlhvTZTjOyybJaJnhGxD0n9k5vZRJfTaitH5GHnbwmc6T2PC+ZpS1FQH+vXyS/UA==} + '@rolldown/binding-android-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.7': - resolution: {integrity: sha512-zokYr1KgRn0hRA89dmgtPj/BmKp9DxgrfAJvOEFfXa8nfYWW2nmgiYIBGpSIAJrEg7Qc/Qznovy6xYwmKh0M8g==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.7': - resolution: {integrity: sha512-eZFjbmrapCBVgMmuLALH3pmQQQStHFuRhsFceJHk6KISW8CkI2e9OPLp9V4qXksrySQcD8XM8fpvGLs5l5C7LQ==} + '@rolldown/binding-darwin-x64@1.0.0-rc.9': + resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.7': - resolution: {integrity: sha512-xjMrh8Dmu2DNwdY6DZsrF6YPGeesc3PaTlkh8v9cqmkSCNeTxnhX3ErhVnuv1j3n8t2IuuhQIwM9eZDINNEt5Q==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': + resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.7': - resolution: {integrity: sha512-mOvftrHiXg4/xFdxJY3T9Wl1/zDAOSlMN8z9an2bXsCwuvv3RdyhYbSMZDuDO52S04w9z7+cBd90lvQSPTAQtw==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': + resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.7': - resolution: {integrity: sha512-TuUkeuEEPRyXMBbJ86NRhAiPNezxHW8merl3Om2HASA9Pl1rI+VZcTtsVQ6v/P0MDIFpSl0k0+tUUze9HIXyEw==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.7': - resolution: {integrity: sha512-G43ZElEvaby+YSOgrXfBgpeQv42LdS0ivFFYQufk2tBDWeBfzE/+ob5DmO8Izbyn4Y8k6GgLF11jFDYNnmU/3w==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.7': - resolution: {integrity: sha512-Y48ShVxGE2zUTt0A0PR3grCLNxW4DWtAfe5lxf6L3uYEQujwo/LGuRogMsAtOJeYLCPTJo2i714LOdnK34cHpw==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.7': - resolution: {integrity: sha512-KU5DUYvX3qI8/TX6D3RA4awXi4Ge/1+M6Jqv7kRiUndpqoVGgD765xhV3Q6QvtABnYjLJenrWDl3S1B5U56ixA==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.7': - resolution: {integrity: sha512-1THb6FdBkAEL12zvUue2bmK4W1+P+tz8Pgu5uEzq+xrtYa3iBzmmKNlyfUzCFNCqsPd8WJEQrYdLcw4iMW4AVw==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.7': - resolution: {integrity: sha512-12o73atFNWDgYnLyA52QEUn9AH8pHIe12W28cmqjyHt4bIEYRzMICvYVCPa2IQm6DJBvCBrEhD9K+ct4wr2hwg==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.7': - resolution: {integrity: sha512-+uUgGwvuUCXl894MTsmTS2J0BnCZccFsmzV7y1jFxW5pTSxkuwL5agyPuDvDOztPeS6RrdqWkn7sT0jRd0ECkg==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.7': - resolution: {integrity: sha512-53p2L/NSy21UiFOqUGlC11kJDZS2Nx2GJRz1QvbkXovypA3cOHbsyZHLkV72JsLSbiEQe+kg4tndUhSiC31UEA==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': + resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.7': - resolution: {integrity: sha512-K6svNRljO6QrL6VTKxwh4yThhlR9DT/tK0XpaFQMnJwwQKng+NYcVEtUkAM0WsoiZHw+Hnh3DGnn3taf/pNYGg==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.7': - resolution: {integrity: sha512-3ZJBT47VWLKVKIyvHhUSUgVwHzzZW761YAIkM3tOT+8ZTjFVp0acCM0Y2Z2j3jCl+XYi2d9y2uEWQ8H0PvvpPw==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.7': - resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + '@rolldown/pluginutils@1.0.0-rc.9': + resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} '@rollup/plugin-json@6.1.0': resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} @@ -2577,8 +2589,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - '@schematics/angular@22.0.0-next.1': - resolution: {integrity: sha512-0Qfjx4hBHfiQ9SaT3pCIMETDt5tZzE0bis8Mojk7F/+ovH1yInNO8UNcClHvBpkho9EzVcdh9GhjHQNlZPCyUQ==} + '@schematics/angular@22.0.0-next.2': + resolution: {integrity: sha512-CYSqFwNDd2ssTIin7T7bJJ+IbacN0H8NXFHzJxsN0dGkmCHR7QegtW2/8/T3XMM1rUdq/nFidlTUq7TgO3BSJg==} engines: {node: ^22.22.0 || >=24.13.1, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} '@sigstore/bundle@4.0.0': @@ -2811,46 +2823,40 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.57.0': - resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} + '@typescript-eslint/eslint-plugin@8.57.1': + resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.0 + '@typescript-eslint/parser': ^8.57.1 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==} + '@typescript-eslint/parser@8.57.1': + resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} 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.56.1': - resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - 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.56.1': - resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} + '@typescript-eslint/project-service@8.57.1': + resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} 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.56.1': - resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} + '@typescript-eslint/scope-manager@8.57.1': + resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/tsconfig-utils@8.57.0': resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} @@ -2858,26 +2864,26 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.0': - resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} + '@typescript-eslint/tsconfig-utils@8.57.1': + resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} 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.56.1': - resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} + '@typescript-eslint/type-utils@8.57.1': + resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} 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.56.1': - resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} + '@typescript-eslint/types@8.57.1': + resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/typescript-estree@8.57.0': resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} @@ -2885,11 +2891,10 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.56.1': - resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} + '@typescript-eslint/typescript-estree@8.57.1': + resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} 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/utils@8.57.0': @@ -2899,19 +2904,26 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.56.1': - resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} + '@typescript-eslint/utils@8.57.1': + resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} 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} - '@vitejs/plugin-basic-ssl@2.1.4': - resolution: {integrity: sha512-HXciTXN/sDBYWgeAD4V4s0DN0g72x5mlxQhHxtYu3Tt8BLa6MzcJZUyDVFCdtjNs3bfENVHVzOsmooTVuNgAAw==} + '@typescript-eslint/visitor-keys@8.57.1': + resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-basic-ssl@2.2.0': + resolution: {integrity: sha512-nmyQ1HGRkfUxjsv3jw0+hMhEdZdrtkvMTdkzRUaRWfiO6PCWw2V2Pz3gldCq96Tn9S8htcgdTxw/gmbLLEbfYw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} peerDependencies: - vite: ^6.0.0 || ^7.0.0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 '@vitest/coverage-v8@4.1.0': resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==} @@ -3099,6 +3111,10 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agent-base@8.0.0: + resolution: {integrity: sha512-QT8i0hCz6C/KQ+KTAbSNwCHDGdmUJl2tp2ZpNlGSWCfhUNVbYG2WLE3MdZGBAgXPV4GAvjGMxo+C1hroyxmZEg==} + engines: {node: '>= 14'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} @@ -3116,12 +3132,12 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - algoliasearch@5.49.1: - resolution: {integrity: sha512-X3Pp2aRQhg4xUC6PQtkubn5NpRKuUPQ9FPDQlx36SmpFwwH2N0/tw4c+NXV3nw3PsgeUs+BuWGP0gjz3TvENLQ==} + algoliasearch@5.49.2: + resolution: {integrity: sha512-1K0wtDaRONwfhL4h8bbJ9qTjmY6rhGgRvvagXkMBsAOMNr+3Q2SffHECh9DIuNVrMA1JwA0zCwhyepgBZVakng==} engines: {node: '>= 14.0.0'} - angular-eslint@21.3.0: - resolution: {integrity: sha512-K4+I41fSxzOavbv87EOnG5rdXiscs31j5pIAQG0aX21OHdSSjFCKOAQNmj8zv5OxUuYj5uYRToR3PuKQSN6i/A==} + angular-eslint@21.3.1: + resolution: {integrity: sha512-VGQWTyuPAEO/AnZuqHxGBJMYSiZ0tbrHx/OgPCRTKHfbrFU4x+zivS84h9UWoDpDtius1RyD+ZReFjTAEWptiA==} peerDependencies: '@angular/cli': '>= 21.0.0 < 22.0.0' eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3237,12 +3253,18 @@ packages: react-native-b4a: optional: true - babel-loader@10.0.0: - resolution: {integrity: sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==} + babel-loader@10.1.1: + resolution: {integrity: sha512-JwKSzk2kjIe7mgPK+/lyZ2QAaJcpahNAdM+hgR2HI8D0OJVkdj8Rl6J3kaLYki9pwF7P2iWnD8qVv80Lq1ABtg==} engines: {node: ^18.20.0 || ^20.10.0 || >=22.0.0} peerDependencies: - '@babel/core': ^7.12.0 + '@babel/core': ^7.12.0 || ^8.0.0-beta.1 + '@rspack/core': ^1.0.0 || ^2.0.0-0 webpack: '>=5.61.0' + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true babel-plugin-polyfill-corejs2@0.4.15: resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} @@ -3622,6 +3644,10 @@ packages: copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + copy-webpack-plugin@14.0.0: resolution: {integrity: sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==} engines: {node: '>= 20.9.0'} @@ -3631,8 +3657,8 @@ packages: core-js-compat@3.48.0: resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} - core-js@3.48.0: - resolution: {integrity: sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==} + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3685,10 +3711,6 @@ packages: engines: {node: '>=4'} hasBin: true - cssstyle@6.2.0: - resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} - engines: {node: '>=20'} - data-uri-to-buffer@6.0.2: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} @@ -3971,8 +3993,8 @@ packages: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint-scope@9.1.1: - resolution: {integrity: sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==} + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} eslint-visitor-keys@3.4.3: @@ -4345,8 +4367,8 @@ packages: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} - hono@4.12.7: - resolution: {integrity: sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==} + hono@4.12.8: + resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} engines: {node: '>=16.9.0'} hosted-git-info@9.0.2: @@ -4416,6 +4438,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + https-proxy-agent@8.0.0: + resolution: {integrity: sha512-YYeW+iCnAS3xhvj2dvVoWgsbca3RfQy/IlaNHHOtDmU0jMqPI9euIq3Y9BJETdxk16h9NHHCKqp/KB9nIMStCQ==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -4618,6 +4644,10 @@ packages: is-what@3.14.1: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -4688,9 +4718,9 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@28.1.0: - resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + jsdom@29.0.0: + resolution: {integrity: sha512-9FshNB6OepopZ08unmmGpsF7/qCjxGPbo3NbgfJAnPeHXnsODE9WWffXZtRFRFe0ntzaAOcSKNJFz8wiyvF1jQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} peerDependencies: canvas: ^3.0.0 peerDependenciesMeta: @@ -4775,8 +4805,8 @@ packages: launch-editor@2.13.1: resolution: {integrity: sha512-lPSddlAAluRKJ7/cjRFoXUFzaX7q/YKI7yPHuEvSJVqoXvFnJov1/Ud87Aa4zULIbA9Nja4mSPK8l0z/7eV2wA==} - less-loader@12.3.1: - resolution: {integrity: sha512-JZZmG7gMzoDP3VGeEG8Sh6FW5wygB5jYL7Wp29FFihuRTsIBacqO3LbRPr2yStYD11riVf13selLm/CPFRDBRQ==} + less-loader@12.3.2: + resolution: {integrity: sha512-uLV5c702ff2jBvO7qewpkLRzkh/I9QW07ur2NKkv8TVTrtX2lrKjEbEU/LLXAn7cgpCIBbkfyUm4qYXCQs5/+w==} engines: {node: '>= 18.12.0'} peerDependencies: '@rspack/core': 0.x || ^1.0.0 || ^2.0.0-0 @@ -4788,16 +4818,16 @@ packages: webpack: optional: true - less@4.4.2: - resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==} - engines: {node: '>=14'} - hasBin: true - less@4.5.1: resolution: {integrity: sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==} engines: {node: '>=14'} hasBin: true + less@4.6.4: + resolution: {integrity: sha512-OJmO5+HxZLLw0RLzkqaNHzcgEAQG7C0y3aMbwtCzIUFZsLMNNq/1IdAdHEycQ58CwUO3jPTHmoN+tE5I7FQxNg==} + engines: {node: '>=18'} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -4820,8 +4850,8 @@ packages: resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==} engines: {node: '>=22.13.0'} - lmdb@3.5.1: - resolution: {integrity: sha512-NYHA0MRPjvNX+vSw8Xxg6FLKxzAG+e7Pt8RqAQA/EehzHVXq9SxDqJIN3JL1hK0dweb884y8kIh6rkWvPyg9Wg==} + lmdb@3.5.2: + resolution: {integrity: sha512-od5AWh1MNylIOeX7MB7TV627MM9tzyOUn8U8FZOeWKpWFnMU5FS9pu5t41pS4+pi7OxHRyk5QVRhuUimHjfkmg==} hasBin: true loader-runner@4.3.1: @@ -4871,6 +4901,10 @@ packages: resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} engines: {node: 20 || >=22} + lru-cache@11.2.7: + resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -5074,8 +5108,8 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} - mini-css-extract-plugin@2.10.0: - resolution: {integrity: sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==} + mini-css-extract-plugin@2.10.1: + resolution: {integrity: sha512-k7G3Y5QOegl380tXmZ68foBRRjE9Ljavx835ObdvmZjQ639izvZD8CS7BkWw1qKPPzHsGL/JDhl0uyU1zc2rJw==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -5384,8 +5418,8 @@ packages: resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} engines: {node: '>= 14'} - pacote@21.4.0: - resolution: {integrity: sha512-DR7mn7HUOomAX1BORnpYy678qVIidbvOojkBscqy27dRKN+s/hLeQT1MeYYrx1Cxh62jyKjiWiDV7RTTqB+ZEQ==} + pacote@21.5.0: + resolution: {integrity: sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true @@ -5759,8 +5793,8 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rolldown@1.0.0-rc.7: - resolution: {integrity: sha512-5X0zEeQFzDpB3MqUWQZyO2TUQqP9VnT7CqXHF2laTFRy487+b6QZyotCazOySAuZLAvplCaOVsg1tVn/Zlmwfg==} + rolldown@1.0.0-rc.9: + resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -5829,6 +5863,11 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + sass@1.98.0: + resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==} + engines: {node: '>=14.0.0'} + hasBin: true + sax@1.5.0: resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} engines: {node: '>=11.0.0'} @@ -6205,8 +6244,8 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - tough-cookie@6.0.0: - resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} engines: {node: '>=16'} tr46@5.1.1: @@ -6296,8 +6335,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.57.0: - resolution: {integrity: sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==} + typescript-eslint@8.57.1: + resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -6322,8 +6361,8 @@ packages: undici-types@7.22.0: resolution: {integrity: sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw==} - undici@7.22.0: - resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + undici@7.24.4: + resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} engines: {node: '>=20.18.1'} unicode-canonical-property-names-ecmascript@2.0.1: @@ -6730,91 +6769,89 @@ packages: snapshots: - '@acemir/cssom@0.9.31': {} - - '@algolia/abtesting@1.15.1': + '@algolia/abtesting@1.15.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-abtesting@5.49.1': + '@algolia/client-abtesting@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-analytics@5.49.1': + '@algolia/client-analytics@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-common@5.49.1': {} + '@algolia/client-common@5.49.2': {} - '@algolia/client-insights@5.49.1': + '@algolia/client-insights@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-personalization@5.49.1': + '@algolia/client-personalization@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-query-suggestions@5.49.1': + '@algolia/client-query-suggestions@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/client-search@5.49.1': + '@algolia/client-search@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/ingestion@1.49.1': + '@algolia/ingestion@1.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/monitoring@1.49.1': + '@algolia/monitoring@1.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/recommend@5.49.1': + '@algolia/recommend@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 + '@algolia/client-common': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 - '@algolia/requester-browser-xhr@5.49.1': + '@algolia/requester-browser-xhr@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 + '@algolia/client-common': 5.49.2 - '@algolia/requester-fetch@5.49.1': + '@algolia/requester-fetch@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 + '@algolia/client-common': 5.49.2 - '@algolia/requester-node-http@5.49.1': + '@algolia/requester-node-http@5.49.2': dependencies: - '@algolia/client-common': 5.49.1 + '@algolia/client-common': 5.49.2 '@ampproject/remapping@2.3.0': dependencies: @@ -6828,21 +6865,21 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/architect@0.2200.0-next.1(chokidar@5.0.0)': + '@angular-devkit/architect@0.2200.0-next.2(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 22.0.0-next.1(chokidar@5.0.0) + '@angular-devkit/core': 22.0.0-next.2(chokidar@5.0.0) rxjs: 7.8.2 transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@22.0.0-next.1(b58f28129b55da2054db6022b2fb7678)': + '@angular-devkit/build-angular@22.0.0-next.2(1d89ba7fcb7784d2422393ab9b59433f)': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2200.0-next.1(chokidar@5.0.0) - '@angular-devkit/build-webpack': 0.2200.0-next.1(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.4(esbuild@0.27.3)))(webpack@5.105.4(esbuild@0.27.3)) - '@angular-devkit/core': 22.0.0-next.1(chokidar@5.0.0) - '@angular/build': 22.0.0-next.1(f13248707630e086f62afa2847b5c70d) - '@angular/compiler-cli': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) + '@angular-devkit/architect': 0.2200.0-next.2(chokidar@5.0.0) + '@angular-devkit/build-webpack': 0.2200.0-next.2(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.4(esbuild@0.27.3)))(webpack@5.105.4(esbuild@0.27.3)) + '@angular-devkit/core': 22.0.0-next.2(chokidar@5.0.0) + '@angular/build': 22.0.0-next.2(1c08417c58e603e54e28921a55c48eb9) + '@angular/compiler-cli': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3) '@babel/core': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-annotate-as-pure': 7.27.3 @@ -6853,10 +6890,10 @@ snapshots: '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@discoveryjs/json-ext': 1.0.0 - '@ngtools/webpack': 22.0.0-next.1(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.3)) + '@ngtools/webpack': 22.0.0-next.2(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.3)) ansi-colors: 4.1.3 autoprefixer: 10.4.27(postcss@8.5.8) - babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.4(esbuild@0.27.3)) + babel-loader: 10.1.1(@babel/core@7.29.0)(webpack@5.105.4(esbuild@0.27.3)) browserslist: 4.28.1 copy-webpack-plugin: 14.0.0(webpack@5.105.4(esbuild@0.27.3)) css-loader: 7.1.4(webpack@5.105.4(esbuild@0.27.3)) @@ -6865,11 +6902,11 @@ snapshots: istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 - less: 4.4.2 - less-loader: 12.3.1(less@4.4.2)(webpack@5.105.4(esbuild@0.27.3)) + less: 4.6.4 + less-loader: 12.3.2(less@4.6.4)(webpack@5.105.4(esbuild@0.27.3)) license-webpack-plugin: 4.0.2(webpack@5.105.4(esbuild@0.27.3)) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.10.0(webpack@5.105.4(esbuild@0.27.3)) + mini-css-extract-plugin: 2.10.1(webpack@5.105.4(esbuild@0.27.3)) open: 11.0.0 ora: 9.3.0 picomatch: 4.0.3 @@ -6878,8 +6915,8 @@ snapshots: postcss-loader: 8.2.1(postcss@8.5.8)(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.3)) resolve-url-loader: 5.0.0 rxjs: 7.8.2 - sass: 1.97.3 - sass-loader: 16.0.7(sass@1.97.3)(webpack@5.105.4(esbuild@0.27.3)) + sass: 1.98.0 + sass-loader: 16.0.7(sass@1.98.0)(webpack@5.105.4(esbuild@0.27.3)) semver: 7.7.4 source-map-loader: 5.0.0(webpack@5.105.4(esbuild@0.27.3)) source-map-support: 0.5.21 @@ -6893,12 +6930,12 @@ snapshots: webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.105.4(esbuild@0.27.3)) optionalDependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) - '@angular/platform-server': 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) - '@angular/ssr': 22.0.0-next.1(96fec6be6d0f7e9eab47b3f9f854d9a9) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) + '@angular/platform-server': 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/ssr': 22.0.0-next.2(f93605c2441543804e2c011df626dcc1) esbuild: 0.27.3 - ng-packagr: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + ng-packagr: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) transitivePeerDependencies: - '@angular/compiler' - '@rspack/core' @@ -6922,9 +6959,9 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.2200.0-next.1(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.4(esbuild@0.27.3)))(webpack@5.105.4(esbuild@0.27.3))': + '@angular-devkit/build-webpack@0.2200.0-next.2(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.4(esbuild@0.27.3)))(webpack@5.105.4(esbuild@0.27.3))': dependencies: - '@angular-devkit/architect': 0.2200.0-next.1(chokidar@5.0.0) + '@angular-devkit/architect': 0.2200.0-next.2(chokidar@5.0.0) rxjs: 7.8.2 webpack: 5.105.4(esbuild@0.27.3) webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.4(esbuild@0.27.3)) @@ -6942,7 +6979,7 @@ snapshots: optionalDependencies: chokidar: 5.0.0 - '@angular-devkit/core@22.0.0-next.1(chokidar@5.0.0)': + '@angular-devkit/core@22.0.0-next.2(chokidar@5.0.0)': dependencies: ajv: 8.18.0 ajv-formats: 3.0.1 @@ -6963,9 +7000,9 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/schematics@22.0.0-next.1(chokidar@5.0.0)': + '@angular-devkit/schematics@22.0.0-next.2(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 22.0.0-next.1(chokidar@5.0.0) + '@angular-devkit/core': 22.0.0-next.2(chokidar@5.0.0) jsonc-parser: 3.3.1 magic-string: 0.30.21 ora: 9.3.0 @@ -6973,55 +7010,55 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-eslint/builder@21.3.0(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/builder@21.3.1(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@angular-devkit/architect': 0.2102.1(chokidar@5.0.0) '@angular-devkit/core': 21.2.1(chokidar@5.0.0) - '@angular/cli': 22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0) + '@angular/cli': 22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - chokidar - '@angular-eslint/bundled-angular-compiler@21.3.0': {} + '@angular-eslint/bundled-angular-compiler@21.3.1': {} - '@angular-eslint/eslint-plugin-template@21.3.0(@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.56.1)(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/eslint-plugin-template@21.3.1(@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.57.0)(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 - '@angular-eslint/template-parser': 21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/utils': 21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/bundled-angular-compiler': 21.3.1 + '@angular-eslint/template-parser': 21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/utils': 21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) aria-query: 5.3.2 axobject-query: 4.1.0 eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 - '@angular-eslint/eslint-plugin@21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/eslint-plugin@21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 - '@angular-eslint/utils': 21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/bundled-angular-compiler': 21.3.1 + '@angular-eslint/utils': 21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 - '@angular-eslint/eslint-plugin@21.3.0(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/eslint-plugin@21.3.1(@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 - '@angular-eslint/utils': 21.3.0(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/bundled-angular-compiler': 21.3.1 + '@angular-eslint/utils': 21.3.1(@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 - '@angular-eslint/schematics@21.3.0(@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(@typescript-eslint/types@8.56.1)(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/schematics@21.3.1(@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(@typescript-eslint/types@8.57.0)(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@angular-devkit/core': 21.2.1(chokidar@5.0.0) '@angular-devkit/schematics': 21.2.1(chokidar@5.0.0) - '@angular-eslint/eslint-plugin': 21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/eslint-plugin-template': 21.3.0(@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.56.1)(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular/cli': 22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0) + '@angular-eslint/eslint-plugin': 21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/eslint-plugin-template': 21.3.1(@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.57.0)(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular/cli': 22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0) ignore: 7.0.5 semver: 7.7.4 strip-json-comments: 3.1.1 @@ -7033,108 +7070,53 @@ snapshots: - eslint - typescript - '@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 + '@angular-eslint/bundled-angular-compiler': 21.3.1 eslint: 9.39.3(jiti@2.6.1) - eslint-scope: 9.1.1 + eslint-scope: 9.1.2 typescript: 5.9.3 - '@angular-eslint/utils@21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/utils@21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/bundled-angular-compiler': 21.3.1 + '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 - '@angular-eslint/utils@21.3.0(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@angular-eslint/utils@21.3.1(@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@angular-eslint/bundled-angular-compiler': 21.3.0 - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/bundled-angular-compiler': 21.3.1 + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 - '@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))': + '@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))': dependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) tslib: 2.8.1 - '@angular/aria@22.0.0-next.0(@angular/cdk@22.0.0-next.0(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))': + '@angular/aria@22.0.0-next.1(@angular/cdk@22.0.0-next.1(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))': dependencies: - '@angular/cdk': 22.0.0-next.0(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + '@angular/cdk': 22.0.0-next.1(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) tslib: 2.8.1 - '@angular/build@22.0.0-next.1(f13248707630e086f62afa2847b5c70d)': - dependencies: - '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2200.0-next.1(chokidar@5.0.0) - '@angular/compiler': 22.0.0-next.2 - '@angular/compiler-cli': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 6.0.8(@types/node@24.10.1) - '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) - beasties: 0.4.1 - browserslist: 4.28.1 - esbuild: 0.27.3 - https-proxy-agent: 7.0.6 - istanbul-lib-instrument: 6.0.3 - jsonc-parser: 3.3.1 - listr2: 10.2.1 - magic-string: 0.30.21 - mrmime: 2.0.1 - parse5-html-rewriting-stream: 8.0.0 - picomatch: 4.0.3 - piscina: 5.1.4 - rolldown: 1.0.0-rc.7 - sass: 1.97.3 - semver: 7.7.4 - source-map-support: 0.5.21 - tinyglobby: 0.2.15 - tslib: 2.8.1 - typescript: 5.9.3 - vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - watchpack: 2.5.1 - optionalDependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) - '@angular/platform-server': 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) - '@angular/ssr': 22.0.0-next.1(96fec6be6d0f7e9eab47b3f9f854d9a9) - less: 4.4.2 - lmdb: 3.5.1 - ng-packagr: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) - postcss: 8.5.8 - vitest: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - transitivePeerDependencies: - - '@types/node' - - chokidar - - jiti - - lightningcss - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - '@angular/build@22.0.0-next.1(fb4e45d759185d3e5b1efa3e6e7773f3)': + '@angular/build@22.0.0-next.2(1c08417c58e603e54e28921a55c48eb9)': dependencies: '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.2200.0-next.1(chokidar@5.0.0) - '@angular/compiler': 22.0.0-next.2 - '@angular/compiler-cli': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) + '@angular-devkit/architect': 0.2200.0-next.2(chokidar@5.0.0) + '@angular/compiler': 22.0.0-next.4 + '@angular/compiler-cli': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3) '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 - '@inquirer/confirm': 6.0.8(@types/node@24.10.1) - '@vitejs/plugin-basic-ssl': 2.1.4(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + '@inquirer/confirm': 6.0.10(@types/node@24.10.1) + '@vitejs/plugin-basic-ssl': 2.2.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2)) beasties: 0.4.1 browserslist: 4.28.1 esbuild: 0.27.3 - https-proxy-agent: 7.0.6 + https-proxy-agent: 8.0.0 istanbul-lib-instrument: 6.0.3 jsonc-parser: 3.3.1 listr2: 10.2.1 @@ -7143,25 +7125,25 @@ snapshots: parse5-html-rewriting-stream: 8.0.0 picomatch: 4.0.3 piscina: 5.1.4 - rolldown: 1.0.0-rc.7 - sass: 1.97.3 + rolldown: 1.0.0-rc.9 + sass: 1.98.0 semver: 7.7.4 source-map-support: 0.5.21 tinyglobby: 0.2.15 tslib: 2.8.1 typescript: 5.9.3 - vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) watchpack: 2.5.1 optionalDependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) - '@angular/platform-server': 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) - '@angular/ssr': 22.0.0-next.1(96fec6be6d0f7e9eab47b3f9f854d9a9) - less: 4.5.1 - lmdb: 3.5.1 - ng-packagr: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) + '@angular/platform-server': 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/ssr': 22.0.0-next.2(f93605c2441543804e2c011df626dcc1) + less: 4.6.4 + lmdb: 3.5.2 + ng-packagr: 22.0.0-next.0(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) postcss: 8.5.8 - vitest: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vitest: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - chokidar @@ -7175,31 +7157,31 @@ snapshots: - tsx - yaml - '@angular/cdk@22.0.0-next.0(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/cdk@22.0.0-next.1(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) parse5: 8.0.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0)': + '@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0)': dependencies: - '@angular-devkit/architect': 0.2200.0-next.1(chokidar@5.0.0) - '@angular-devkit/core': 22.0.0-next.1(chokidar@5.0.0) - '@angular-devkit/schematics': 22.0.0-next.1(chokidar@5.0.0) - '@inquirer/prompts': 8.3.0(@types/node@24.10.1) - '@listr2/prompt-adapter-inquirer': 4.2.1(@inquirer/prompts@8.3.0(@types/node@24.10.1))(@types/node@24.10.1)(listr2@10.2.1) + '@angular-devkit/architect': 0.2200.0-next.2(chokidar@5.0.0) + '@angular-devkit/core': 22.0.0-next.2(chokidar@5.0.0) + '@angular-devkit/schematics': 22.0.0-next.2(chokidar@5.0.0) + '@inquirer/prompts': 8.3.2(@types/node@24.10.1) + '@listr2/prompt-adapter-inquirer': 4.2.1(@inquirer/prompts@8.3.2(@types/node@24.10.1))(@types/node@24.10.1)(listr2@10.2.1) '@modelcontextprotocol/sdk': 1.27.1 - '@schematics/angular': 22.0.0-next.1(chokidar@5.0.0) + '@schematics/angular': 22.0.0-next.2(chokidar@5.0.0) '@yarnpkg/lockfile': 1.1.0 - algoliasearch: 5.49.1 + algoliasearch: 5.49.2 ini: 6.0.0 jsonc-parser: 3.3.1 listr2: 10.2.1 npm-package-arg: 13.0.2 - pacote: 21.4.0 + pacote: 21.5.0 parse5-html-rewriting-stream: 8.0.0 semver: 7.7.4 yargs: 18.0.0 @@ -7210,15 +7192,15 @@ snapshots: - chokidar - supports-color - '@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3)': + '@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3)': dependencies: - '@angular/compiler': 22.0.0-next.2 + '@angular/compiler': 22.0.0-next.4 '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -7232,76 +7214,76 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@22.0.0-next.2': + '@angular/compiler@22.0.0-next.4': dependencies: tslib: 2.8.1 - '@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)': + '@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.0.0-next.2 + '@angular/compiler': 22.0.0-next.4 - '@angular/elements@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@angular/elements@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/forms@22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/forms@22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/language-service@22.0.0-next.2': {} + '@angular/language-service@22.0.0-next.4': {} - '@angular/platform-browser-dynamic@22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))': + '@angular/platform-browser-dynamic@22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/compiler': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/compiler': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) tslib: 2.8.1 - '@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))': + '@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/animations': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) - '@angular/platform-server@22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/compiler': 22.0.0-next.2 - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/compiler': 22.0.0-next.4 + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2)': + '@angular/router@22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ssr@22.0.0-next.1(96fec6be6d0f7e9eab47b3f9f854d9a9)': + '@angular/ssr@22.0.0-next.2(f93605c2441543804e2c011df626dcc1)': dependencies: - '@angular/common': 22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2) - '@angular/router': 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/common': 22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2) + '@angular/core': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2) + '@angular/router': 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@angular/platform-server': 22.0.0-next.2(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.2)(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.2(@angular/animations@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(@angular/common@22.0.0-next.2(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(rxjs@7.8.2)))(rxjs@7.8.2) + '@angular/platform-server': 22.0.0-next.4(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-next.4)(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(@angular/platform-browser@22.0.0-next.4(@angular/animations@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(@angular/common@22.0.0-next.4(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(rxjs@7.8.2)))(rxjs@7.8.2) '@asamuzakjp/css-color@5.0.1': dependencies: @@ -7309,15 +7291,15 @@ snapshots: '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - lru-cache: 11.2.6 + lru-cache: 11.2.7 - '@asamuzakjp/dom-selector@6.8.1': + '@asamuzakjp/dom-selector@7.0.3': dependencies: '@asamuzakjp/nwsapi': 2.3.9 bidi-js: 1.0.3 css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.6 + lru-cache: 11.2.7 '@asamuzakjp/nwsapi@2.3.9': {} @@ -8019,7 +8001,9 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.0': {} + '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 '@csstools/css-tokenizer@4.0.0': {} @@ -8194,9 +8178,9 @@ snapshots: '@harperfast/extended-iterable@1.0.3': optional: true - '@hono/node-server@1.19.11(hono@4.12.7)': + '@hono/node-server@1.19.11(hono@4.12.8)': dependencies: - hono: 4.12.7 + hono: 4.12.8 '@humanfs/core@0.19.1': {} @@ -8305,29 +8289,29 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@inquirer/ansi@2.0.3': {} + '@inquirer/ansi@2.0.4': {} - '@inquirer/checkbox@5.1.0(@types/node@24.10.1)': + '@inquirer/checkbox@5.1.2(@types/node@24.10.1)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/confirm@6.0.8(@types/node@24.10.1)': + '@inquirer/confirm@6.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/core@11.1.5(@types/node@24.10.1)': + '@inquirer/core@11.1.7(@types/node@24.10.1)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/ansi': 2.0.4 + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.10.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.0 mute-stream: 3.0.0 @@ -8335,88 +8319,88 @@ snapshots: optionalDependencies: '@types/node': 24.10.1 - '@inquirer/editor@5.0.8(@types/node@24.10.1)': + '@inquirer/editor@5.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/external-editor': 2.0.3(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/external-editor': 2.0.4(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/expand@5.0.8(@types/node@24.10.1)': + '@inquirer/expand@5.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/external-editor@2.0.3(@types/node@24.10.1)': + '@inquirer/external-editor@2.0.4(@types/node@24.10.1)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: '@types/node': 24.10.1 - '@inquirer/figures@2.0.3': {} + '@inquirer/figures@2.0.4': {} - '@inquirer/input@5.0.8(@types/node@24.10.1)': + '@inquirer/input@5.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/number@4.0.8(@types/node@24.10.1)': + '@inquirer/number@4.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/password@5.0.8(@types/node@24.10.1)': + '@inquirer/password@5.0.10(@types/node@24.10.1)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/prompts@8.3.0(@types/node@24.10.1)': - dependencies: - '@inquirer/checkbox': 5.1.0(@types/node@24.10.1) - '@inquirer/confirm': 6.0.8(@types/node@24.10.1) - '@inquirer/editor': 5.0.8(@types/node@24.10.1) - '@inquirer/expand': 5.0.8(@types/node@24.10.1) - '@inquirer/input': 5.0.8(@types/node@24.10.1) - '@inquirer/number': 4.0.8(@types/node@24.10.1) - '@inquirer/password': 5.0.8(@types/node@24.10.1) - '@inquirer/rawlist': 5.2.4(@types/node@24.10.1) - '@inquirer/search': 4.1.4(@types/node@24.10.1) - '@inquirer/select': 5.1.0(@types/node@24.10.1) + '@inquirer/prompts@8.3.2(@types/node@24.10.1)': + dependencies: + '@inquirer/checkbox': 5.1.2(@types/node@24.10.1) + '@inquirer/confirm': 6.0.10(@types/node@24.10.1) + '@inquirer/editor': 5.0.10(@types/node@24.10.1) + '@inquirer/expand': 5.0.10(@types/node@24.10.1) + '@inquirer/input': 5.0.10(@types/node@24.10.1) + '@inquirer/number': 4.0.10(@types/node@24.10.1) + '@inquirer/password': 5.0.10(@types/node@24.10.1) + '@inquirer/rawlist': 5.2.6(@types/node@24.10.1) + '@inquirer/search': 4.1.6(@types/node@24.10.1) + '@inquirer/select': 5.1.2(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/rawlist@5.2.4(@types/node@24.10.1)': + '@inquirer/rawlist@5.2.6(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/search@4.1.4(@types/node@24.10.1)': + '@inquirer/search@4.1.6(@types/node@24.10.1)': dependencies: - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 - '@inquirer/select@5.1.0(@types/node@24.10.1)': + '@inquirer/select@5.1.2(@types/node@24.10.1)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.5(@types/node@24.10.1) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.1) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.10.1) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.10.1) optionalDependencies: '@types/node': 24.10.1 @@ -8424,6 +8408,10 @@ snapshots: optionalDependencies: '@types/node': 24.10.1 + '@inquirer/type@4.0.4(@types/node@24.10.1)': + optionalDependencies: + '@types/node': 24.10.1 + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.3 @@ -8588,38 +8576,38 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.1(@inquirer/prompts@8.3.0(@types/node@24.10.1))(@types/node@24.10.1)(listr2@10.2.1)': + '@listr2/prompt-adapter-inquirer@4.2.1(@inquirer/prompts@8.3.2(@types/node@24.10.1))(@types/node@24.10.1)(listr2@10.2.1)': dependencies: - '@inquirer/prompts': 8.3.0(@types/node@24.10.1) + '@inquirer/prompts': 8.3.2(@types/node@24.10.1) '@inquirer/type': 4.0.3(@types/node@24.10.1) listr2: 10.2.1 transitivePeerDependencies: - '@types/node' - '@lmdb/lmdb-darwin-arm64@3.5.1': + '@lmdb/lmdb-darwin-arm64@3.5.2': optional: true - '@lmdb/lmdb-darwin-x64@3.5.1': + '@lmdb/lmdb-darwin-x64@3.5.2': optional: true - '@lmdb/lmdb-linux-arm64@3.5.1': + '@lmdb/lmdb-linux-arm64@3.5.2': optional: true - '@lmdb/lmdb-linux-arm@3.5.1': + '@lmdb/lmdb-linux-arm@3.5.2': optional: true - '@lmdb/lmdb-linux-x64@3.5.1': + '@lmdb/lmdb-linux-x64@3.5.2': optional: true - '@lmdb/lmdb-win32-arm64@3.5.1': + '@lmdb/lmdb-win32-arm64@3.5.2': optional: true - '@lmdb/lmdb-win32-x64@3.5.1': + '@lmdb/lmdb-win32-x64@3.5.2': optional: true '@modelcontextprotocol/sdk@1.27.1': dependencies: - '@hono/node-server': 1.19.11(hono@4.12.7) + '@hono/node-server': 1.19.11(hono@4.12.8) ajv: 8.18.0 ajv-formats: 3.0.1 content-type: 1.0.5 @@ -8629,7 +8617,7 @@ snapshots: eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.3.0(express@5.2.1) - hono: 4.12.7 + hono: 4.12.8 jose: 6.2.0 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -8741,9 +8729,9 @@ snapshots: seedrandom: 3.0.5 uuid: 8.3.2 - '@ngtools/webpack@22.0.0-next.1(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.3))': + '@ngtools/webpack@22.0.0-next.2(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.3))': dependencies: - '@angular/compiler-cli': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) + '@angular/compiler-cli': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3) typescript: 5.9.3 webpack: 5.105.4(esbuild@0.27.3) @@ -8766,7 +8754,7 @@ snapshots: agent-base: 7.1.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - lru-cache: 11.2.6 + lru-cache: 11.2.7 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -9003,54 +8991,54 @@ snapshots: - react-native-b4a - supports-color - '@rolldown/binding-android-arm64@1.0.0-rc.7': + '@rolldown/binding-android-arm64@1.0.0-rc.9': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.7': + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.7': + '@rolldown/binding-darwin-x64@1.0.0-rc.9': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.7': + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.7': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.7': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.7': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.7': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.7': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.7': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.7': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.7': + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.7': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.7': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.7': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': optional: true - '@rolldown/pluginutils@1.0.0-rc.7': {} + '@rolldown/pluginutils@1.0.0-rc.9': {} '@rollup/plugin-json@6.1.0(rollup@4.59.0)': dependencies: @@ -9157,10 +9145,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - '@schematics/angular@22.0.0-next.1(chokidar@5.0.0)': + '@schematics/angular@22.0.0-next.2(chokidar@5.0.0)': dependencies: - '@angular-devkit/core': 22.0.0-next.1(chokidar@5.0.0) - '@angular-devkit/schematics': 22.0.0-next.1(chokidar@5.0.0) + '@angular-devkit/core': 22.0.0-next.2(chokidar@5.0.0) + '@angular-devkit/schematics': 22.0.0-next.2(chokidar@5.0.0) jsonc-parser: 3.3.1 transitivePeerDependencies: - chokidar @@ -9442,14 +9430,14 @@ snapshots: '@types/node': 24.10.1 optional: true - '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/type-utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 eslint: 9.39.3(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -9458,59 +9446,59 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(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 + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@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/project-service@8.57.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.56.1': - dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 - '@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.56.1(typescript@5.9.3)': + '@typescript-eslint/scope-manager@8.57.1': dependencies: - typescript: 5.9.3 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 '@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.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.57.1(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.3(jiti@2.6.1))(typescript@5.9.3) + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.3(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -9518,16 +9506,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.56.1': {} - '@typescript-eslint/types@8.57.0': {} - '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + '@typescript-eslint/types@8.57.1': {} + + '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@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 @@ -9537,12 +9525,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.57.1(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 + '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.4 @@ -9552,43 +9540,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@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.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) - '@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/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.56.1': + '@typescript-eslint/visitor-keys@8.57.0': dependencies: - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.57.0 eslint-visitor-keys: 5.0.1 - '@typescript-eslint/visitor-keys@8.57.0': + '@typescript-eslint/visitor-keys@8.57.1': dependencies: - '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/types': 8.57.1 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))': + '@vitejs/plugin-basic-ssl@2.2.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: - vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) - '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.0 @@ -9600,7 +9588,7 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.0.3 - vitest: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vitest: 4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) '@vitest/expect@4.1.0': dependencies: @@ -9611,13 +9599,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.1.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))': + '@vitest/mocker@4.1.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) '@vitest/pretty-format@4.1.0': dependencies: @@ -9934,6 +9922,8 @@ snapshots: agent-base@7.1.4: {} + agent-base@8.0.0: {} + ajv-formats@2.1.1: dependencies: ajv: 8.18.0 @@ -9961,38 +9951,38 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.49.1: - dependencies: - '@algolia/abtesting': 1.15.1 - '@algolia/client-abtesting': 5.49.1 - '@algolia/client-analytics': 5.49.1 - '@algolia/client-common': 5.49.1 - '@algolia/client-insights': 5.49.1 - '@algolia/client-personalization': 5.49.1 - '@algolia/client-query-suggestions': 5.49.1 - '@algolia/client-search': 5.49.1 - '@algolia/ingestion': 1.49.1 - '@algolia/monitoring': 1.49.1 - '@algolia/recommend': 5.49.1 - '@algolia/requester-browser-xhr': 5.49.1 - '@algolia/requester-fetch': 5.49.1 - '@algolia/requester-node-http': 5.49.1 - - angular-eslint@21.3.0(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript-eslint@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(typescript@5.9.3): + algoliasearch@5.49.2: + dependencies: + '@algolia/abtesting': 1.15.2 + '@algolia/client-abtesting': 5.49.2 + '@algolia/client-analytics': 5.49.2 + '@algolia/client-common': 5.49.2 + '@algolia/client-insights': 5.49.2 + '@algolia/client-personalization': 5.49.2 + '@algolia/client-query-suggestions': 5.49.2 + '@algolia/client-search': 5.49.2 + '@algolia/ingestion': 1.49.2 + '@algolia/monitoring': 1.49.2 + '@algolia/recommend': 5.49.2 + '@algolia/requester-browser-xhr': 5.49.2 + '@algolia/requester-fetch': 5.49.2 + '@algolia/requester-node-http': 5.49.2 + + angular-eslint@21.3.1(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript-eslint@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(typescript@5.9.3): dependencies: '@angular-devkit/core': 21.2.1(chokidar@5.0.0) '@angular-devkit/schematics': 21.2.1(chokidar@5.0.0) - '@angular-eslint/builder': 21.3.0(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/eslint-plugin': 21.3.0(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/eslint-plugin-template': 21.3.0(@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.56.1)(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/schematics': 21.3.0(@angular-eslint/template-parser@21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@angular/cli@22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0))(@typescript-eslint/types@8.56.1)(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular-eslint/template-parser': 21.3.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@angular/cli': 22.0.0-next.1(@types/node@24.10.1)(chokidar@5.0.0) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/builder': 21.3.1(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/eslint-plugin': 21.3.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/eslint-plugin-template': 21.3.1(@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/types@8.57.0)(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/schematics': 21.3.1(@angular-eslint/template-parser@21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(@angular/cli@22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0))(@typescript-eslint/types@8.57.0)(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(chokidar@5.0.0)(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular-eslint/template-parser': 21.3.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@angular/cli': 22.0.0-next.2(@types/node@24.10.1)(chokidar@5.0.0) + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 - typescript-eslint: 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + typescript-eslint: 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - chokidar - supports-color @@ -10085,10 +10075,11 @@ snapshots: b4a@1.8.0: {} - babel-loader@10.0.0(@babel/core@7.29.0)(webpack@5.105.4(esbuild@0.27.3)): + babel-loader@10.1.1(@babel/core@7.29.0)(webpack@5.105.4(esbuild@0.27.3)): dependencies: '@babel/core': 7.29.0 find-up: 5.0.0 + optionalDependencies: webpack: 5.105.4(esbuild@0.27.3) babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): @@ -10291,7 +10282,7 @@ snapshots: '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 glob: 13.0.6 - lru-cache: 11.2.6 + lru-cache: 11.2.7 minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.5 @@ -10512,6 +10503,10 @@ snapshots: dependencies: is-what: 3.14.1 + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + copy-webpack-plugin@14.0.0(webpack@5.105.4(esbuild@0.27.3)): dependencies: glob-parent: 6.0.2 @@ -10525,7 +10520,7 @@ snapshots: dependencies: browserslist: 4.28.1 - core-js@3.48.0: {} + core-js@3.49.0: {} core-util-is@1.0.3: {} @@ -10581,13 +10576,6 @@ snapshots: cssesc@3.0.0: {} - cssstyle@6.2.0: - dependencies: - '@asamuzakjp/css-color': 5.0.1 - '@csstools/css-syntax-patches-for-csstree': 1.1.0 - css-tree: 3.2.1 - lru-cache: 11.2.6 - data-uri-to-buffer@6.0.2: {} data-urls@7.0.0: @@ -10813,11 +10801,11 @@ snapshots: dependencies: eslint: 9.39.3(jiti@2.6.1) - eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1)): + eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1)): dependencies: eslint: 9.39.3(jiti@2.6.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint-scope@5.1.1: dependencies: @@ -10829,7 +10817,7 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-scope@9.1.1: + eslint-scope@9.1.2: dependencies: '@types/esrecurse': 4.3.1 '@types/estree': 1.0.8 @@ -11283,7 +11271,7 @@ snapshots: highlight.js@11.11.1: {} - hono@4.12.7: {} + hono@4.12.8: {} hosted-git-info@9.0.2: dependencies: @@ -11390,6 +11378,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@8.0.0: + dependencies: + agent-base: 8.0.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} hyperdyperid@1.2.0: {} @@ -11540,6 +11535,8 @@ snapshots: is-what@3.14.1: {} + is-what@4.1.16: {} + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -11606,24 +11603,24 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@28.1.0: + jsdom@29.0.0: dependencies: - '@acemir/cssom': 0.9.31 - '@asamuzakjp/dom-selector': 6.8.1 + '@asamuzakjp/css-color': 5.0.1 + '@asamuzakjp/dom-selector': 7.0.3 '@bramus/specificity': 2.4.2 + '@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1) '@exodus/bytes': 1.15.0 - cssstyle: 6.2.0 + css-tree: 3.2.1 data-urls: 7.0.0 decimal.js: 10.6.0 html-encoding-sniffer: 6.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.7 parse5: 8.0.0 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 6.0.0 - undici: 7.22.0 + tough-cookie: 6.0.1 + undici: 7.24.4 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -11631,7 +11628,6 @@ snapshots: xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' - - supports-color jsesc@3.1.0: {} @@ -11728,13 +11724,13 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.3 - less-loader@12.3.1(less@4.4.2)(webpack@5.105.4(esbuild@0.27.3)): + less-loader@12.3.2(less@4.6.4)(webpack@5.105.4(esbuild@0.27.3)): dependencies: - less: 4.4.2 + less: 4.6.4 optionalDependencies: webpack: 5.105.4(esbuild@0.27.3) - less@4.4.2: + less@4.5.1: dependencies: copy-anything: 2.0.6 parse-node-version: 1.0.1 @@ -11748,11 +11744,10 @@ snapshots: needle: 3.3.1 source-map: 0.6.1 - less@4.5.1: + less@4.6.4: dependencies: - copy-anything: 2.0.6 + copy-anything: 3.0.5 parse-node-version: 1.0.1 - tslib: 2.8.1 optionalDependencies: errno: 0.1.8 graceful-fs: 4.2.11 @@ -11790,7 +11785,7 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 10.0.0 - lmdb@3.5.1: + lmdb@3.5.2: dependencies: '@harperfast/extended-iterable': 1.0.3 msgpackr: 1.11.8 @@ -11799,13 +11794,13 @@ snapshots: ordered-binary: 1.6.1 weak-lru-cache: 1.2.2 optionalDependencies: - '@lmdb/lmdb-darwin-arm64': 3.5.1 - '@lmdb/lmdb-darwin-x64': 3.5.1 - '@lmdb/lmdb-linux-arm': 3.5.1 - '@lmdb/lmdb-linux-arm64': 3.5.1 - '@lmdb/lmdb-linux-x64': 3.5.1 - '@lmdb/lmdb-win32-arm64': 3.5.1 - '@lmdb/lmdb-win32-x64': 3.5.1 + '@lmdb/lmdb-darwin-arm64': 3.5.2 + '@lmdb/lmdb-darwin-x64': 3.5.2 + '@lmdb/lmdb-linux-arm': 3.5.2 + '@lmdb/lmdb-linux-arm64': 3.5.2 + '@lmdb/lmdb-linux-x64': 3.5.2 + '@lmdb/lmdb-win32-arm64': 3.5.2 + '@lmdb/lmdb-win32-x64': 3.5.2 optional: true loader-runner@4.3.1: {} @@ -11854,6 +11849,8 @@ snapshots: lru-cache@11.2.6: {} + lru-cache@11.2.7: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -12154,7 +12151,7 @@ snapshots: mimic-function@5.0.1: {} - mini-css-extract-plugin@2.10.0(webpack@5.105.4(esbuild@0.27.3)): + mini-css-extract-plugin@2.10.1(webpack@5.105.4(esbuild@0.27.3)): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 @@ -12300,10 +12297,10 @@ snapshots: netmask@2.0.2: {} - ng-packagr@22.0.0-next.0(@angular/compiler-cli@22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): + ng-packagr@22.0.0-next.0(@angular/compiler-cli@22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.0.0-next.2(@angular/compiler@22.0.0-next.2)(typescript@5.9.3) + '@angular/compiler-cli': 22.0.0-next.4(@angular/compiler@22.0.0-next.4)(typescript@5.9.3) '@rollup/plugin-json': 6.1.0(rollup@4.59.0) '@rollup/wasm-node': 4.59.0 ajv: 8.18.0 @@ -12541,7 +12538,7 @@ snapshots: degenerator: 5.0.1 netmask: 2.0.2 - pacote@21.4.0: + pacote@21.5.0: dependencies: '@gar/promise-retry': 1.0.2 '@npmcli/git': 7.0.2 @@ -12941,26 +12938,26 @@ snapshots: rfdc@1.4.1: {} - rolldown@1.0.0-rc.7: + rolldown@1.0.0-rc.9: dependencies: '@oxc-project/types': 0.115.0 - '@rolldown/pluginutils': 1.0.0-rc.7 + '@rolldown/pluginutils': 1.0.0-rc.9 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.7 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.7 - '@rolldown/binding-darwin-x64': 1.0.0-rc.7 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.7 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.7 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.7 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.7 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.7 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.7 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.7 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.7 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.7 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.7 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.7 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.7 + '@rolldown/binding-android-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-x64': 1.0.0-rc.9 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9 rollup-plugin-dts@6.3.0(rollup@4.59.0)(typescript@5.9.3): dependencies: @@ -13033,11 +13030,11 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.7(sass@1.97.3)(webpack@5.105.4(esbuild@0.27.3)): + sass-loader@16.0.7(sass@1.98.0)(webpack@5.105.4(esbuild@0.27.3)): dependencies: neo-async: 2.6.2 optionalDependencies: - sass: 1.97.3 + sass: 1.98.0 webpack: 5.105.4(esbuild@0.27.3) sass@1.97.3: @@ -13048,6 +13045,14 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.6 + sass@1.98.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + sax@1.5.0: optional: true @@ -13528,7 +13533,7 @@ snapshots: toidentifier@1.0.1: {} - tough-cookie@6.0.0: + tough-cookie@6.0.1: dependencies: tldts: 7.0.24 @@ -13617,12 +13622,12 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -13638,7 +13643,7 @@ snapshots: undici-types@7.22.0: {} - undici@7.22.0: {} + undici@7.24.4: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -13689,7 +13694,7 @@ snapshots: vary@1.1.2: {} - vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -13701,32 +13706,15 @@ snapshots: '@types/node': 24.10.1 fsevents: 2.3.3 jiti: 2.6.1 - less: 4.4.2 - sass: 1.97.3 - terser: 5.46.0 - yaml: 2.8.2 - - vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): - 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.10.1 - fsevents: 2.3.3 - jiti: 2.6.1 - less: 4.5.1 - sass: 1.97.3 + less: 4.6.4 + sass: 1.98.0 terser: 5.46.0 yaml: 2.8.2 - vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@28.1.0)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vitest@4.1.0(@types/node@24.10.1)(jiti@2.6.1)(jsdom@29.0.0)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + '@vitest/mocker': 4.1.0(vite@7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -13743,11 +13731,11 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.5.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.10.1)(jiti@2.6.1)(less@4.6.4)(sass@1.98.0)(terser@5.46.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.1 - jsdom: 28.1.0 + jsdom: 29.0.0 transitivePeerDependencies: - jiti - less diff --git a/projects/folderCrud/tsconfig.json b/projects/folderCrud/tsconfig.json index ca5034fd..6485cc8a 100644 --- a/projects/folderCrud/tsconfig.json +++ b/projects/folderCrud/tsconfig.json @@ -1,7 +1,6 @@ { "compilerOptions": { "outDir": "../../dist/folderCrud", - "downlevelIteration": false, "experimentalDecorators": true, "strict": true, "allowSyntheticDefaultImports": true, diff --git a/projects/se-ng/signal-utils/API.json b/projects/se-ng/signal-utils/API.json index 3a3619e9..ed0624bc 100644 --- a/projects/se-ng/signal-utils/API.json +++ b/projects/se-ng/signal-utils/API.json @@ -20,14 +20,14 @@ "name": "debouncedSignal", "category": "Reactive", "signature": "debouncedSignal(fn, {delay?, equal?}) => WritableSignal", - "description": "Debounce a computed signal", + "description": "Throttle-with-trailing-catch-up for a computed signal. Emits the initial value immediately; during a burst emits at most once per delay ms (window anchored to the first change); the last value in the burst window is picked up when the window closes. For short bursts the behaviour matches classical trailing-edge debounce. No injection context required. Proxies set/update to the source when fn is a WritableSignal.", "source": "src/reactive/debounced-computed.ts" }, { "name": "debouncedComputed", "category": "Reactive", "signature": "debouncedComputed(fn, {delay?, equal?}) => Signal", - "description": "Readonly debounced signal", + "description": "Readonly variant of debouncedSignal. Same throttle-with-trailing-catch-up semantics; returns a read-only Signal.", "source": "src/reactive/debounced-computed.ts" }, { @@ -40,15 +40,15 @@ { "name": "injectAwaitSignal", "category": "Reactive", - "signature": "injectAwaitSignal(injector?) => (signalFn, predicate) => Promise", - "description": "Factory that returns an awaitSignal bound to an injector", + "signature": "injectAwaitSignal(injector?) => (signalFn, predicate, abortSignal?) => Promise", + "description": "Factory that returns an awaitSignal bound to an injector. Supports optional AbortSignal for cancellation.", "source": "src/reactive/await-signal.ts" }, { "name": "awaitSignal", "category": "Reactive", - "signature": "awaitSignal(signalFn, predicate) => Promise", - "description": "Wait for a signal to satisfy a predicate", + "signature": "awaitSignal(signalFn, predicate, abortSignal?) => Promise", + "description": "Wait for a signal to satisfy a predicate. Rejects via AbortSignal if provided and aborted. NG0950 (required input not yet set) is silently retried.", "source": "src/reactive/await-signal.ts" }, { diff --git a/projects/se-ng/signal-utils/README.md b/projects/se-ng/signal-utils/README.md index bf32920b..01c194e1 100644 --- a/projects/se-ng/signal-utils/README.md +++ b/projects/se-ng/signal-utils/README.md @@ -51,32 +51,50 @@ indications, examples, and source links. // access current value: resource().value(); resource().status ``` -- **`debouncedSignal` / `debouncedComputed`** — debounce helpers for signals. +- **`debouncedSignal` / `debouncedComputed`** — throttle-with-trailing-catch-up helpers for signals. - `debouncedSignal(fn, {delay?, equal?}) => WritableSignal` - `debouncedComputed(...) => Signal` - Source: [`src/reactive/debounced-computed.ts`](./src/reactive/debounced-computed.ts) + Behavior: the initial value is always emitted immediately. During a burst of + changes at most one new value is propagated per `delay` ms — the window is + anchored to the **first** change in each interval. The latest value in a burst + window is picked up when the window closes. For short bursts (silence longer + than `delay`) the behaviour is identical to classical trailing-edge debounce. + Uses `linkedSignal` internally, so **no injection context is required**. + When `fn` is itself a `WritableSignal`, `.set()` and `.update()` are proxied + back to the source signal. + Example: ```ts const debounced = debouncedSignal(() => searchTerm(), { delay: 200 }); - // debounced.asReadonly() or debounced() to read + // During rapid typing debounced() updates at most every 200 ms; + // the final search term is always captured when typing stops. ``` - **`injectAwaitSignal` / `awaitSignal`** — wait for a signal to - satisfy a predicate. - - `awaitSignal(signalFn, predicate) => Promise` - - `injectAwaitSignal(injector?) => (signalFn, predicate) => Promise` + satisfy a predicate, with optional cancellation via `AbortSignal`. + - `awaitSignal(signalFn, predicate, abortSignal?) => Promise` + - `injectAwaitSignal(injector?) => (signalFn, predicate, abortSignal?) => Promise` - Source: [`src/reactive/await-signal.ts`](./src/reactive/await-signal.ts) + Behaviour: + - Resolves with the signal value as soon as `predicate` returns `true`. + - Rejects with the error if `predicate` or the signal itself throws (NG0950 is silently retried). + - If an `AbortSignal` is provided and aborted, the promise rejects with `abortSignal.reason` and the internal effect is destroyed. + - If no `AbortSignal` is provided, the promise simply stays pending until the predicate is satisfied or the context is destroyed (and is then garbage-collected without an unhandled rejection). + Example: ```ts - await awaitSignal( - () => readyFlag(), - v => v === true - ); - // resolves when readyFlag() becomes true + // Basic usage + await awaitSignal(() => readyFlag(), v => v === true); + + // With cancellation (e.g. bound to component lifetime) + const controller = new AbortController(); + inject(DestroyRef).onDestroy(() => controller.abort()); + await awaitSignal(() => readyFlag(), v => v === true, controller.signal); ``` --- diff --git a/projects/se-ng/signal-utils/src/reactive/await-signal.spec.ts b/projects/se-ng/signal-utils/src/reactive/await-signal.spec.ts index 42c094d3..561194cd 100644 --- a/projects/se-ng/signal-utils/src/reactive/await-signal.spec.ts +++ b/projects/se-ng/signal-utils/src/reactive/await-signal.spec.ts @@ -36,24 +36,24 @@ describe('awaitSignal', () => { await expect(result).resolves.toBe(5); }); - it('rejects when the signal is destroyed before resolving', async () => { + it('rejects with abort reason when AbortSignal is aborted', async () => { const sig = runInInjectionContext(injector, () => signal(0)); + const controller = new AbortController(); const result = runInInjectionContext(injector, () => - awaitSignal(sig, v => v === 5) + awaitSignal(sig, v => v === 5, controller.signal) ); - setTimeout(() => sig.set(4), 1); - - /** - * there is trickery here! - * We are using the setTimeout to trigger the thing _after_ this completes. - * however the the teardown logic will still run, and it will clean up the signal. - * This means that the signal will be destroyed before the predicate has a chance to be satisfied. - * and the rejects will happen. (assertion is awaited to avoid Vitest warning) - */ + controller.abort(new Error('cancelled')); + await expect(result).rejects.toThrow('cancelled'); + }); - await expect(result).rejects.toThrow( - '[awaitSignal] the provided signal was destroyed before the predicate was satisfied' + it('rejects with the native AbortError when AbortSignal aborts without a reason', async () => { + const sig = runInInjectionContext(injector, () => signal(0)); + const controller = new AbortController(); + const result = runInInjectionContext(injector, () => + awaitSignal(sig, v => v === 5, controller.signal) ); + controller.abort(); + await expect(result).rejects.toThrow('This operation was aborted'); }); it('rejects if predicate throws', async () => { @@ -67,6 +67,27 @@ describe('awaitSignal', () => { ).rejects.toThrow('fail'); }); + it('silently retries when signal throws NG0950 before resolving', async () => { + const underlying = runInInjectionContext(injector, () => signal(0)); + // Simulates input.required() before a value is bound: throws NG0950 until the value is set + const requiredLikeSig = () => { + const v = underlying(); + if (v === 0) throw new Error('NG0950: Required input is accessed before a value is set.'); + return v; + }; + + const result = runInInjectionContext(injector, () => + awaitSignal(requiredLikeSig, v => v === 5) + ); + + // Force the initial effect run NOW (v=0 → throws NG0950, silently ignored) + TestBed.flushEffects(); + // Now set the real value — triggers a second run that resolves + underlying.set(5); + + await expect(result).resolves.toBe(5); + }); + it('works with injectAwaitSignal in injection context', async () => { const sig = runInInjectionContext(injector, () => signal('ok')); const result = await runInInjectionContext(injector, () => diff --git a/projects/se-ng/signal-utils/src/reactive/await-signal.ts b/projects/se-ng/signal-utils/src/reactive/await-signal.ts index 5047636a..0462af95 100644 --- a/projects/se-ng/signal-utils/src/reactive/await-signal.ts +++ b/projects/se-ng/signal-utils/src/reactive/await-signal.ts @@ -3,11 +3,10 @@ import { inject, Injector, runInInjectionContext, - type Signal } from '@angular/core'; import { Deferred } from '../async/deferred'; -export type Predicate = (source: Partial | T) => boolean; +export type Predicate = (source: T) => boolean; /** * Returns an awaitSignal function that runs in the current injection context @@ -18,53 +17,50 @@ export const injectAwaitSignal = (injector = inject(Injector)) => { * Waits for a signal to satisfy a given predicate and returns a promise that resolves with the signal's value. * * @template T - The type of the signal's value. - * @param {Signal} signal - The signal to watch. + * @param {() => T} signal - The signal to watch. * @param {Predicate} predicate - The predicate function to test the signal's value. + * @param {AbortSignal} [abortSignal] - Optional AbortSignal to cancel the wait. * @returns {Promise} A promise that resolves with the signal's value when the predicate is satisfied. - * - * @throws {Error} If the signal is destroyed before the predicate is satisfied. */ - return (signal: () => T, predicate: Predicate): Promise => - runInInjectionContext(injector, () => awaitSignal(signal, predicate)); + return (signal: () => T, predicate: Predicate, abortSignal?: AbortSignal): Promise => + runInInjectionContext(injector, () => awaitSignal(signal, predicate, abortSignal)); }; /** * Waits for a signal to satisfy a given predicate and returns a promise that resolves with the signal's value. * * @template T - The type of the signal's value. - * @param {Signal} signal - The signal to watch. + * @param {() => T} signal - The signal to watch. * @param {Predicate} predicate - The predicate function to test the signal's value. + * @param {AbortSignal} [abortSignal] - Optional AbortSignal to cancel the wait. * @returns {Promise} A promise that resolves with the signal's value when the predicate is satisfied. - * - * @throws {Error} If the signal is destroyed before the predicate is satisfied. */ export const awaitSignal = ( signal: () => T, - predicate: Predicate + predicate: Predicate, + abortSignal?: AbortSignal ): Promise => { const deferred = new Deferred(); - const effectRef = effect( - onCleanUp => { + + const effectRef = effect(() => { + try { const result = signal(); - try { - if (predicate(result)) { - deferred.resolve(result); - effectRef.destroy(); // stop watching the signal, we are done! - } - } catch (e) { - deferred.reject(e); - effectRef.destroy(); + if (predicate(result)) { + deferred.resolve(result); + effectRef.destroy(); // stop watching the signal, we are done! } - onCleanUp(() => { - deferred.reject( - new Error( - '[awaitSignal] the provided signal was destroyed before the predicate was satisfied' - ) - ); - }); - }, - { debugName: 'awaitSignal' } - ); + } catch (e) { + // NG0950: required input not yet set — wait for the next signal change + if (e instanceof Error && e.message.startsWith('NG0950')) return; + deferred.reject(e); + effectRef.destroy(); + } + }, { debugName: 'awaitSignal' }); + + abortSignal?.addEventListener('abort', () => { + deferred.reject(abortSignal.reason); + effectRef.destroy(); + }); return deferred.promise; }; diff --git a/projects/se-ng/signal-utils/src/reactive/debounced-computed.spec.ts b/projects/se-ng/signal-utils/src/reactive/debounced-computed.spec.ts index e7a951c4..e0b7ea98 100644 --- a/projects/se-ng/signal-utils/src/reactive/debounced-computed.spec.ts +++ b/projects/se-ng/signal-utils/src/reactive/debounced-computed.spec.ts @@ -61,6 +61,7 @@ describe('debouncedSignal / debouncedComputed', () => { // rapid updates src.set(2); + expect(deb()).toBe(1); // reading here triggers the computation and starts the debounce window now += 10; vi.advanceTimersByTime(10); @@ -158,6 +159,7 @@ describe('debouncedSignal / debouncedComputed', () => { expect(deb()).toBe(1); src.set(2); + expect(deb()).toBe(1); // reading here triggers the computation and starts the debounce window now += 51; vi.advanceTimersByTime(51); expect(deb()).toBe(2); @@ -189,6 +191,7 @@ describe('debouncedSignal / debouncedComputed', () => { expect(deb()).toBe(1); src.set(2); + expect(deb()).toBe(1); // reading here triggers the computation and starts the debounce window now += 21; vi.advanceTimersByTime(21); @@ -220,6 +223,28 @@ describe('debouncedSignal / debouncedComputed', () => { ).toThrow('[debouncedSignal] delay must be a positive number'); }); + it('proxies set and update to the source signal when fn is a WritableSignal', () => { + let now = Date.now(); + const dateSpy = vi.spyOn(Date, 'now').mockImplementation(() => now); + + const src = TestBed.runInInjectionContext(() => signal(1)); + const deb = TestBed.runInInjectionContext(() => + debouncedSignal(src, { delay: 50 }) + ); + + expect(deb()).toBe(1); + + // .set() on the debounced signal should write through to the source + deb.set(42); + expect(src()).toBe(42); + + // .update() on the debounced signal should write through to the source + deb.update(v => v + 1); + expect(src()).toBe(43); + + dateSpy.mockRestore(); + }); + it('throws when delay is zero or negative for debouncedComputed', () => { const src = TestBed.runInInjectionContext(() => signal(1)); expect(() => diff --git a/projects/se-ng/signal-utils/src/reactive/debounced-computed.ts b/projects/se-ng/signal-utils/src/reactive/debounced-computed.ts index cd724226..550f4b5c 100644 --- a/projects/se-ng/signal-utils/src/reactive/debounced-computed.ts +++ b/projects/se-ng/signal-utils/src/reactive/debounced-computed.ts @@ -1,4 +1,5 @@ import { + isWritableSignal, linkedSignal, type Signal, signal, @@ -7,45 +8,57 @@ import { } from '@angular/core'; /** - * Debounce a state. it will only emit a new value after the delay has passed. - * Uses a linkedSignal under the hood. It will return the initial value immediately, - * and then wait for the delay to pass before updating the value. - * @param {() => T} function returning the value to be debounced, evaluated in a reactive context - * @returns {*} {Signal} + * Throttles a signal, emitting the latest value at most once per `delay` ms. + * + * Behavior differs from classical trailing-edge debounce: + * - The **initial value** is returned immediately (signals require an initial value). + * - During a burst of changes a new value is emitted every `delay` ms — the window + * is anchored to the **first** change in each interval, not the last. Changes + * that arrive within the active window are suppressed; the latest of them is + * picked up when the window closes. + * - If the burst is **shorter** than `delay` the observable behaviour is identical + * to trailing-edge debounce: one emission after the burst ends. + * + * Use this when you want to prevent update storms while still keeping consumers + * reasonably current during a sustained burst. If you need true trailing-edge + * debounce (emit only after `delay` ms of silence) you need a different primitive. + * + * Uses a `linkedSignal` under the hood so no injection context is required. + * + * @param fn Reactive function whose value should be throttled, evaluated in a reactive context. + * @returns A `WritableSignal` that proxies `set`/`update` to the source signal + * when `fn` is itself a `WritableSignal`. */ export const debouncedSignal = ( fn: () => T, options: { /** - * The delay in milliseconds, defaults to 500 + * The throttle window in milliseconds. At most one emission per window. + * Defaults to 500. */ delay?: number; /** - * equality function, passed to the linkedSignal + * Equality function passed to the underlying `linkedSignal`. + * Prevents downstream propagation when the throttled value has not changed. */ equal?: ValueEqualityFn> | undefined; } ): WritableSignal => { let decayTime: number | undefined; - let currentResult: T; - let initialized = false; const delay = options.delay ?? 500; if (delay <= 0) { throw new Error('[debouncedSignal] delay must be a positive number'); } - /* c8 ignore start */ const triggerSignal = signal(0); - /* c8 ignore stop */ - return linkedSignal({ + const linked: WritableSignal = linkedSignal({ source: () => ({ value: fn(), time: triggerSignal() }), - computation: ({ value, time }) => { + computation: ({ value, time }, previous) => { // Initialize once with the very first value seen - if (!initialized) { - currentResult = value; - initialized = true; + if (!previous) { + return value; } if (!decayTime) { @@ -58,26 +71,41 @@ export const debouncedSignal = ( } if (decayTime < Date.now()) { - // update the current result with the latest value when the decay has passed - currentResult = value; decayTime = undefined; // clear the timeout + return value; // update the value if the decay time has passed } - return currentResult; + return previous.value; // return the previous value if we're still within the decay window }, - equal: options.equal + equal: options.equal, + debugName: 'debouncedSignal' }); + + // when the original signal, we proxy the set and update method to the linked signal, so that the user can use the same API as a normal signal + if (isWritableSignal(fn as unknown as Signal)) { + const originSignal = fn as unknown as WritableSignal; + linked.set = originSignal.set; + linked.update = originSignal.update; + } + return linked; }; +/** + * Read-only variant of `debouncedSignal`. Returns a `Signal` that throttles + * the source reactive function to at most one emission per `delay` ms. + * + * See `debouncedSignal` for full behavior notes. + */ export const debouncedComputed = ( fn: () => T, options: { /** - * The delay in milliseconds, defaults to 500 + * The throttle window in milliseconds. At most one emission per window. + * Defaults to 500. */ delay?: number; /** - * equality function, passed to the linkedSignal + * Equality function passed to the underlying `linkedSignal`. */ equal?: ValueEqualityFn> | undefined; } diff --git a/quickTsExperiments/signals/tsconfig.json b/quickTsExperiments/signals/tsconfig.json index 2ea88505..f35ad27a 100644 --- a/quickTsExperiments/signals/tsconfig.json +++ b/quickTsExperiments/signals/tsconfig.json @@ -3,7 +3,6 @@ // Setting the "baseUrl" to a different directory than "packages/" because otherwise // packages like the native "http" module are resolved to the Angular "http" package. "declaration": true, - "downlevelIteration": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": true, diff --git a/sec-issues.md b/sec-issues.md new file mode 100644 index 00000000..e9237c30 --- /dev/null +++ b/sec-issues.md @@ -0,0 +1,168 @@ +# Security Issues Report + +Generated: March 10, 2026 + +--- + +## Critical Issues + +### 1. Hardcoded API Credentials + +**File:** `src/app/tumblr/tumblr.component.ts:23` + +```typescript +const apiKey = `RSIq08oTL7lA1DyETOmqujDSph7rvP4akG8NRPz9os6ywJjBhE`; +const clientId = 'e972ca06cc4b961'; +``` + +**Risk:** API key and client ID are hardcoded in source code. These credentials are exposed in the client-side bundle and can be extracted by anyone viewing the application. + +**Recommendation:** Move sensitive credentials to environment files or a backend proxy service. Never include API keys in client-side code. + +--- + +### 2. XSS via innerHTML with bypassSecurityTrustHtml + +**Files:** + +- `src/app/blogs/blogs.component.ts:64` +- `projects/slido/src/app/slide/slide.component.ts:63` + +```typescript +return this.san.bypassSecurityTrustHtml(html); +``` + +**Risk:** Using `bypassSecurityTrustHtml()` disables Angular's built-in XSS protection. If the loaded content (markdown files from `/assets/articles/`) can be controlled by attackers, they could inject malicious scripts. + +**Recommendation:** + +- Validate and sanitize all content before rendering +- Consider using DOMPurify in addition to Angular's sanitizer +- Use Content Security Policy (CSP) headers + +--- + +### 3. Unsafe innerHTML Assignment (Intentional Demo) + +**File:** `src/app/dynamichtml/dynamichtml.component.ts:121` + +```typescript +/** DANGER AHEAD */ target.innerHTML = newHtml; +``` + +**Risk:** This is intentionally unsafe code for demonstration purposes. However, if this pattern exists elsewhere or the comment is removed in production, it creates a critical XSS vulnerability. + +**Recommendation:** Remove or comment out this dangerous pattern. Use the sanitized version on line 129 instead. + +--- + +## High Issues + +### 4. Unauthenticated MQTT Connection + +**File:** `src/app/mqtt/mqtt.service.ts:24` + +```typescript +m.default.connectAsync(`wss://mqtt.eliasweb.nl`); +``` + +**Risk:** The MQTT service connects to a WebSocket MQTT broker without authentication. This could allow unauthorized access to Zigbee device data and control. + +**Recommendation:** Implement authentication (username/password or TLS certificates) for MQTT connections. + +--- + +### 5. localStorage for Sensitive Data + +**File:** `src/app/mqtt/pair-button/pair-button.component.ts:87,101` + +```typescript +const storedRouter = localStorage.getItem(lsKey); +localStorage.setItem(lsKey, selected); +``` + +**Risk:** Storing device-related data in localStorage is accessible via XSS attacks and persists on shared devices. + +**Recommendation:** Use sessionStorage for less sensitive data, or implement proper encryption if storage is required. + +--- + +### 6. Direct DOM Manipulation + +**Files:** + +- `src/app/icon-sprite/icon-sprite.component.ts` +- `src/app/custom-native-form/digit-input/digit-input.component.ts` +- `src/app/mqtt/pretty-json/pj.ts` + +**Risk:** Extensive use of `document.createElement()`, `document.body.insertBefore()`, and similar DOM APIs bypass Angular's change detection and security model. + +**Recommendation:** Prefer Angular's rendering engine and template binding. If DOM manipulation is necessary, ensure proper sanitization. + +--- + +## Medium Issues + +### 7. Unsafe URL Construction + +**File:** `src/app/dyn-route/dyn-routes.routes.ts:15` + +```typescript +const option = (new URL(window.location.href).searchParams.get('comp') ?? ... +``` + +**Risk:** Using URL parameters directly without validation could lead to injection attacks or navigation to malicious URLs. + +**Recommendation:** Validate and sanitize all URL parameters before use. + +--- + +### 8. Global Window Variable Exposure + +**File:** `src/app/rvt/template/template.component.ts:100` + +```typescript +window.templateForm = form; +``` + +**Risk:** Exposing components or forms on the global `window` object makes them accessible to any JavaScript on the page, including potential XSS payloads. + +**Recommendation:** Avoid attaching Angular components to the global scope. + +--- + +## Low Issues + +### 9. Debug/Hardcoded URLs in Production Code + +**Files:** + +- MQTT broker URL: `wss://mqtt.eliasweb.nl` +- Imgur API: `https://api.imgur.com/3/gallery/t/` + +**Risk:** Hardcoded URLs make it difficult to manage environment-specific configurations and may expose internal infrastructure. + +**Recommendation:** Use environment variables or configuration services for all URLs. + +--- + +## Summary + +| Severity | Count | +| -------- | ----- | +| Critical | 3 | +| High | 3 | +| Medium | 2 | +| Low | 1 | + +**Overall Assessment:** The codebase contains several security issues, primarily around XSS vulnerabilities and hardcoded credentials. The most urgent issues to address are the hardcoded API key in the Tumblr component and the XSS vulnerabilities in the blogs component. + +--- + +## Recommendations Priority + +1. **Immediately:** Remove or rotate the exposed API key +2. **High Priority:** Review and sanitize all uses of `bypassSecurityTrustHtml()` and `innerHTML` +3. **High Priority:** Add authentication to MQTT connection +4. **Medium Priority:** Review localStorage usage for sensitive data +5. **Ongoing:** Conduct regular security audits diff --git a/src/app/crud-stuff/relations.service.ts b/src/app/crud-stuff/relations.service.ts index d21c9fef..6d6ab8b5 100644 --- a/src/app/crud-stuff/relations.service.ts +++ b/src/app/crud-stuff/relations.service.ts @@ -64,6 +64,9 @@ export class RelationsService { filter = signal(''); #filter = debouncedComputed(() => `(?i)${this.filter()}`, { delay: 250 }); //debounce and wrap it inside an couchDB regex. #refresh = signal(0); + // guard to avoid repeatedly attempting database creation when multiple + // errors fire in quick succession (prevents repeated PUT // calls) + #dbCreateAttempted = false; sort = signal('name'); order = signal<'asc' | 'desc'>('asc'); @@ -111,6 +114,13 @@ export class RelationsService { return; } const reason: string = err.error?.reason; + // If CouchDB reports the DB already exists (HTTP 412 / file_exists), + // ignore — this is benign and should not trigger repeated create attempts. + if (err?.status === 412 || err?.error?.error === 'file_exists' || (typeof reason === 'string' && reason.toLowerCase().includes('file exists'))) { + console.info('CouchDB database already exists, ignoring create.', err); + return; + } + if (!reason) { console.error('Unknown error', err); this.#notifyDialog.show({ @@ -131,6 +141,11 @@ export class RelationsService { } } if (reason.startsWith('Database does not exist')) { + if (this.#dbCreateAttempted) { + console.info('Database create already attempted, skipping.'); + return; + } + this.#dbCreateAttempted = true; console.error('Database not found, creating it'); try { await untracked( diff --git a/src/app/crud-stuff/utils/earlyread-undefined.ts b/src/app/crud-stuff/utils/earlyread-undefined.ts index 13ed5d91..f5c251dd 100644 --- a/src/app/crud-stuff/utils/earlyread-undefined.ts +++ b/src/app/crud-stuff/utils/earlyread-undefined.ts @@ -6,7 +6,7 @@ import type { Signal } from '@angular/core'; * @param data * @returns */ -export const earlyReadToUndefined = (data: Signal): T | undefined => { +export const earlyReadToUndefined = (data: Signal | (() => T)): T | undefined => { try { return data(); } catch (err) { diff --git a/src/app/grid-play/logged-in-user.service.ts b/src/app/grid-play/logged-in-user.service.ts index ce6af62e..091b7820 100644 --- a/src/app/grid-play/logged-in-user.service.ts +++ b/src/app/grid-play/logged-in-user.service.ts @@ -18,6 +18,7 @@ export class LoggedIn { ); user = computed(() => { + if (!this.#isBrowser) return undefined; if (!this.#userRs.hasValue()) return undefined; const userName = this.#userRs.value()?.data?.username || ''; return userName ? userName : undefined; // if username is empty string, treat as not logged in, so return undefined instead diff --git a/src/app/metered-view/gauge/gauge.component.css b/src/app/metered-view/gauge/gauge.component.css index 26228044..7de29e0a 100644 --- a/src/app/metered-view/gauge/gauge.component.css +++ b/src/app/metered-view/gauge/gauge.component.css @@ -3,13 +3,13 @@ --_block-size: 100px; display: inline-block; position: relative; - width: var(--_inline-size); - height: var(--_block-size); + inline-size: var(--_inline-size); + block-size: var(--_block-size); } svg.myGauge { - width: var(--_inline-size); - height: var(--_block-size); + inline-size: var(--_inline-size); + block-size: var(--_block-size); --_meter-backgroundColor: var(--meter-backgroundColor, var(--surface-3)); background-repeat: no-repeat; background-position: center; diff --git a/src/app/metered-view/gauge/gauge.component.ts b/src/app/metered-view/gauge/gauge.component.ts index a91e29d6..c4938dd7 100644 --- a/src/app/metered-view/gauge/gauge.component.ts +++ b/src/app/metered-view/gauge/gauge.component.ts @@ -12,8 +12,6 @@ import { @@ -31,8 +29,8 @@ import { diff --git a/src/app/mqtt/mqtt-device-settings.service.ts b/src/app/mqtt/mqtt-device-settings.service.ts index 1a932307..3dc23249 100644 --- a/src/app/mqtt/mqtt-device-settings.service.ts +++ b/src/app/mqtt/mqtt-device-settings.service.ts @@ -10,6 +10,7 @@ import { effect, inject, Injectable, + Injector, signal, untracked } from '@angular/core'; @@ -18,6 +19,10 @@ import { firstValueFrom } from 'rxjs'; import { LoggedIn } from '../grid-play/logged-in-user.service'; import { addCachingContext, HttpCache } from '../util/http-cache-system'; +import type { + MqttDeviceOptions, + MqttDeviceSetting +} from './mqtt-device-settings.types'; import { couchEventLister } from '../crud-stuff/couch-event-lister'; import { goAddData } from '../crud-stuff/couch-helpers'; @@ -33,36 +38,50 @@ const httpCachedOptions: Record = { }) }; -const sortFields = ['id', 'friendlyName'] as const; -export type SortField = (typeof sortFields)[number]; - -export interface MqttDeviceSetting { - id: string; // the device id, also used as the document id in CouchDB - _rev?: string; // the CouchDB revision, used for updates and deletes - friendlyName: string; // the user friendly name for the device - maxPower: number; // the maximum power usage of this device, used for calculating percentages in the UI - isSubDevice?: boolean; // whether this device is a subDevice of another device (exclude it when totalling up power usage, for example) - allowPowerControl?: boolean; // whether the device can be turned on/off remotely - alertWhenOff?: boolean; // whether to show an alert when the device is turned off while it should be on (for devices that should always be on, like a fridge) - alertWhenLost?: boolean; // whether to show an alert when the device is not reachable (for devices that should always be reachable, like a router) -} - -export type MqttDeviceOptions = Omit< - MqttDeviceSetting, - 'id' | '_rev' | 'friendlyName' | 'maxPower' ->; - @Injectable({ providedIn: 'root' }) export class MqttDeviceSettingsService { user = inject(LoggedIn).user; + injector = inject(Injector); base = computed( () => `https://${this.user() === undefined ? 'demodb' : 'couchdb'}.eliasweb.nl` as const ); baseUrl = computed(() => `${this.base()}/mqtt_device_settings` as const); - idUrl = (id: string) => `${this.baseUrl()}/${id}`; + idUrl = (id: string, rev?: string) => + `${this.baseUrl()}/${id}${rev ? `?rev=${rev}` : ''}`; + + readonly defaultOptions: MqttDeviceOptions = { + alertWhenLost: false, + alertWhenOff: false, + allowPowerControl: false, + isSubDevice: false + } as const; + + readonly extractedOptions = ( + options: Partial | MqttDeviceOptions + ): MqttDeviceOptions => ({ + alertWhenLost: options?.alertWhenLost ?? this.defaultOptions.alertWhenLost, + alertWhenOff: options?.alertWhenOff ?? this.defaultOptions.alertWhenOff, + allowPowerControl: + options?.allowPowerControl ?? this.defaultOptions.allowPowerControl, + isSubDevice: options?.isSubDevice ?? this.defaultOptions.isSubDevice, + maxPower: options?.maxPower + }); + + optionsFromDevResource = ( + resource: HttpResourceRef> + ) => + computed( + () => { + if (resource.isLoading()) return this.defaultOptions; + const data = resource.hasValue() && resource.value(); + if (!data) return this.defaultOptions; + return this.extractedOptions(data); + }, + { debugName: 'OptionsFromDevResource' } + ); #http = inject(HttpClient); #notifyDialog = inject(NotifyDialogService); @@ -71,21 +90,27 @@ export class MqttDeviceSettingsService { #refresh = signal(0); + // guard to avoid repeatedly attempting database creation when multiple + // errors fire in quick succession (prevents repeated PUT // calls) + #dbCreateAttempted = false; #listRes = httpResource<[string, string][]>( - () => ({ - url: `${this.baseUrl()}/_all_docs?include_docs=false&v=${this.#refresh()}`, - method: 'POST', - body: { - fields: ['id', '_rev'] - }, - credentials: 'include', - mode: 'cors' - }), + () => + this.user() === undefined // don't attempt to load the list if we don't know the user, + ? undefined + : { + url: `${this.baseUrl()}/_all_docs?include_docs=false&v=${this.#refresh()}`, + method: 'POST', + body: { + fields: ['id', '_rev'] + }, + credentials: 'include', + mode: 'cors' + }, { defaultValue: [], parse: (response: any) => - (response?.docs ?? []).map( - (i: any) => [i.id, i._rev] as [string, string] + (response?.rows ?? []).map( + (i: any) => [i.id, i.value.rev] as [string, string] ) } ); @@ -97,6 +122,18 @@ export class MqttDeviceSettingsService { const err: any = this.#listRes.error(); if (!err) return; const reason: string = err.error?.reason; + + // If CouchDB reports the DB already exists (HTTP 412 / file_exists), + // ignore — this is benign and should not trigger repeated create attempts. + if ( + err?.status === 412 || + err?.error?.error === 'file_exists' || + (typeof reason === 'string' && + reason.toLowerCase().includes('file exists')) + ) { + return; + } + if (!reason) { console.error('Unknown error', err); this.#notifyDialog.show({ @@ -105,13 +142,30 @@ export class MqttDeviceSettingsService { }); return; } + if (reason.startsWith('No index exists')) { throw new Error( 'Index missing, please create the required database and indexes by running the createDbAndIndexes function in the console.' ); } if (reason.startsWith('Database does not exist')) { + if (this.#dbCreateAttempted) { + console.info('Database create already attempted, skipping.'); + return; + } + this.#dbCreateAttempted = true; try { + // Double-check with a direct fetch to avoid issuing a PUT if the DB + // already exists (this helps when multiple instances or retries race). + const checkRes = await fetch(this.baseUrl(), { + method: 'GET', + credentials: 'include', + mode: 'cors' + }); + if (checkRes.ok) { + this.#listRes.reload(); + return; + } await untracked( async () => await firstValueFrom( @@ -132,20 +186,30 @@ export class MqttDeviceSettingsService { constructor() { setTimeout(() => { + if (!this.user()) return; // don't set up the listener if we don't know the user (e.g. not logged in) const s = couchEventLister(this.base(), 'mqtt_device_settings').subscribe( event => { + console.log('CouchDB change event'); + // console.log(JSON.stringify(event, null, 2)); this.#cache.purge(this.idUrl(event.id)); if (event.deleted) { this.#list.update(oldList => oldList.filter(i => i[0] !== event.id) ); } else { - const rev = event.changes[0]?.rev ?? ''; - this.#list.update(oldList => - oldList.map(i => - i[0] === event.id ? ([i[0], rev] as [string, string]) : i - ) - ); + const rev = event.changes[0]?.rev ?? Date.now().toString(36); + this.#list.update(oldList => { + // Find the item index once, then update or append accordingly. + const idx = oldList.findIndex(i => i[0] === event.id); + if (idx === -1) { + // Not present: append new id/rev tuple. + return [...oldList, [event.id, rev]]; + } else { + const newList = [...oldList]; + newList[idx] = [event.id, rev]; + return newList; + } + }); } } ); @@ -154,14 +218,16 @@ export class MqttDeviceSettingsService { } create = async (data: MqttDeviceSetting) => { + if (!data?.id) return false; const url = this.idUrl(data.id); try { const response = await firstValueFrom( this.#http.put(url, data, httpCachedOptions) ); - this.#list.update(oldList => - [[data.id, ''] as [string, string], ...oldList].splice(0, 50) - ); + this.#list.update(oldList => [ + [data.id, ''] as [string, string], + ...oldList + ]); return true; } catch (e: any) { const { error: { error: err, reason } = {} } = e ?? {}; @@ -178,32 +244,42 @@ export class MqttDeviceSettingsService { }; read = ( - ids: Signal, + ids: () => string | undefined, options: Record = httpCachedOptions ): HttpResourceRef> => { const id = computed(() => earlyReadToUndefined(ids) ?? ''); + // use the list signal to get the current revision for this id, so that the resource updates when the revision changes (e.g. after an update or external change) + const rev = computed(() => { + const list = earlyReadToUndefined(this.list) ?? []; + const item = list.find(i => i[0] === id()); + return item ? item[1] : undefined; + }); const httpOptions = computed(() => { if (!id()) return undefined; - return { url: this.idUrl(id()), ...options }; + return { url: this.idUrl(id(), rev()), ...options }; }); return httpResource>( httpOptions, { - defaultValue: { id: id() } as unknown as Partial + defaultValue: { id: id() } as unknown as Partial, + injector: this.injector } ); }; update = async (data: MqttDeviceSetting) => { - const id = data.id; + const id = data?.id; + if (!id) return { result: 'error', error: 'missing-id' }; const url = this.idUrl(id); const oldData = (await firstValueFrom( this.#http.get(url, httpCachedOptions) )) as MqttDeviceSetting; - if (deepEqual(oldData, data)) return { result: 'noChange' }; + // Ensure we include the current revision when updating so CouchDB accepts the PUT + const toSend = { ...data, _rev: oldData._rev } as MqttDeviceSetting; + if (deepEqual(oldData, toSend)) return { result: 'noChange' }; try { const { rev } = await firstValueFrom( - this.#http.put(url, data, httpCachedOptions) + this.#http.put(url, toSend, httpCachedOptions) ); this.#list.update(oldList => oldList.reduce( @@ -226,15 +302,16 @@ export class MqttDeviceSettingsService { } if (reason?.startsWith('Document update conflict')) { try { - this.#cache.purge(url); + this.#cache.purge(url); // purge the cache to avoid repeated conflicts on retry const myDiff = deepDiff(oldData, data); const remoteData = (await firstValueFrom( - this.#http.get(url, { mode: 'cors', credentials: 'include' }) + this.#http.get(url, { mode: 'cors', credentials: 'include' }) // don't use cache here to ensure we get the latest revision and data, even if it's a bit slower )) as MqttDeviceSetting; console.log({ myDiff, remoteData }); const merged = { ...remoteData, ...myDiff, + // for maxPower, we want to keep the highest value to avoid losing important data about power usage maxPower: Math.max( remoteData.maxPower || 0, data.maxPower || 0, @@ -280,11 +357,11 @@ export class MqttDeviceSettingsService { const { _rev } = await firstValueFrom( this.#http.get<{ _rev: string }>(url, httpCachedOptions) ); - this.#list.update(oldList => - oldList.map(i => + this.#list.update(oldList => [ + ...oldList.map(i => i[0] === id ? ([i[0], _rev] as [string, string]) : i ) - ); + ]); return false; } } diff --git a/src/app/mqtt/mqtt-device-settings.types.ts b/src/app/mqtt/mqtt-device-settings.types.ts new file mode 100644 index 00000000..a889c8ca --- /dev/null +++ b/src/app/mqtt/mqtt-device-settings.types.ts @@ -0,0 +1,22 @@ +export const sortFields = ['id', 'friendlyName'] as const; + +export type SortField = (typeof sortFields)[number]; + +export interface MqttDeviceSetting { + id: string; + _rev?: string; + friendlyName: string; + maxPower: number; + isSubDevice?: boolean; + allowPowerControl?: boolean; + alertWhenOff?: boolean; + alertWhenLost?: boolean; +} + +export type MqttDeviceOptions = { + isSubDevice: boolean; + allowPowerControl: boolean; + alertWhenOff: boolean; + alertWhenLost: boolean; + maxPower?: number; +}; diff --git a/src/app/mqtt/mqtt.component copy.css b/src/app/mqtt/mqtt.component copy.css deleted file mode 100644 index 71311962..00000000 --- a/src/app/mqtt/mqtt.component copy.css +++ /dev/null @@ -1,4 +0,0 @@ -img { - width: 75px; - aspect-ratio: 1; -} diff --git a/src/app/mqtt/mqtt.component copy.ts b/src/app/mqtt/mqtt.component copy.ts deleted file mode 100644 index ff775141..00000000 --- a/src/app/mqtt/mqtt.component copy.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { JsonPipe } from '@angular/common'; -import type { OnDestroy } from '@angular/core'; -import { Component, inject } from '@angular/core'; -import { - filter, - map, - repeat, - share, - switchMap, - takeUntil, - tap, - timer -} from 'rxjs'; - -import { observableComputed } from '../signal-utils'; - -@Component({ - selector: 'app-mqtt', - standalone: true, - imports: [JsonPipe], - templateUrl: './mqtt.component.html', - styleUrl: './mqtt.component.css' -}) -export class MqttComponent implements OnDestroy { - mqtt = inject(MqttService); - - button$ = this.mqtt.listenFor('LichtknopBuro/action').pipe( - share(), - tap(msg => console.log(msg)) - ); - lamp$ = this.mqtt - .listenFor('Buro licht panel') - .pipe(tap(msg => console.log(msg))) - .subscribe(); - brightDown_down$ = this.button$.pipe( - filter(msg => msg === 'brightness_down_hold') - ); - brightDown_up$ = this.button$.pipe( - filter(msg => msg === 'brightness_down_release') - ); - - $state = observableComputed(() => - this.mqtt.listenFor('bridge/devices').pipe( - map(s => JSON.parse(s) as Z2MDevices[]), - tap(console.log) - ) - ); - - sub = this.brightDown_down$ - .pipe( - switchMap(() => timer(0, 100)), - takeUntil(this.brightDown_up$), - repeat() - ) - .subscribe(data => { - console.log(data); - }); - - ngOnDestroy() { - this.sub.unsubscribe(); - this.lamp$.unsubscribe(); - } -} - -interface MqttMessage { - topic: string; - message: string; -} diff --git a/src/app/mqtt/mqtt.component.css b/src/app/mqtt/mqtt.component.css index e850a177..3b3a670d 100644 --- a/src/app/mqtt/mqtt.component.css +++ b/src/app/mqtt/mqtt.component.css @@ -43,6 +43,37 @@ div.toolbar { } } +.searchBar { + main { + display: flex; + align-items: center; + gap: 0.5rem; + + label { + display: inline-flex; + align-items: center; + gap: 0.35rem; + background: transparent; + padding: 0.25rem 0.5rem; + border-radius: 0.5rem; + } + + label:has(button) { + background: var(--surface-3); + gap:0; + padding: 0; + margin: 0 + } + } +} + +@media (max-width: 700px) { + .searchBar main { + flex-direction: column; + align-items: flex-start; + } +} + div.devGrid { margin-block-start: 1rem; display: grid; diff --git a/src/app/mqtt/mqtt.component.html b/src/app/mqtt/mqtt.component.html index 8b7cd520..45b95aa3 100644 --- a/src/app/mqtt/mqtt.component.html +++ b/src/app/mqtt/mqtt.component.html @@ -7,39 +7,75 @@ {{ pf ? pf : 'Alles' }} } -
- - - -
- - @if (sd.checked) { -
- - - + + + + +
- @for (device of powerMeters(); track device.ieee_address) { - + @for (device of powerMetersFiltered(); track device.ieeeAddress) { + }
diff --git a/src/app/mqtt/mqtt.component.ts b/src/app/mqtt/mqtt.component.ts index b69f2f0d..d12e04dc 100644 --- a/src/app/mqtt/mqtt.component.ts +++ b/src/app/mqtt/mqtt.component.ts @@ -1,36 +1,39 @@ import { - afterRenderEffect, ChangeDetectionStrategy, Component, computed, inject, - linkedSignal, - signal + Injector } from '@angular/core'; -import { rxResource } from '@angular/core/rxjs-interop'; -import { deepEqual } from '@se-ng/signal-utils'; -import { EMPTY } from 'rxjs'; +import { debouncedComputed, deepEqual } from '@se-ng/signal-utils'; import { AuthenticadedUserOnlyComponent } from '../authenticaded-user-only/authenticaded-user-only.component'; import { StackedPerComponent } from '../metered-view/stacked-per/stacked-per.component'; -import { MqttService } from './mqtt.service'; +import { httpResource } from '@angular/common/http'; +import { MqttDeviceSettingsService } from './mqtt-device-settings.service'; import { PairButtonComponent } from './pair-button/pair-button.component'; import { extractPrefix, PowerMeterComponent } from './power-meter/power-meter.component'; -import { PrettyJson } from './pretty-json/pretty-json.component'; +import { + type BulkGetResponse, + type CouchDoc, + type DeviceStatus, + type DeviceWithSetting, + type ParsedDeviceSettings, + type SearchState +} from './mqtt.component.types'; +import { zigbeePrefixes, type ZigbeePrefixes } from './zigbee-prefixes.types'; import { persistentSignal } from './util/idbstorage'; -import { ZigbeeService } from './zigbee.service'; +import { undefinedWhenEmpty, ZigbeeService } from './zigbee.service'; -export const zigbeePrefixes = ['e&m', 's&m', `zaak`, 'kamp', 'Alles'] as const; -export type ZigbeePrefixes = (typeof zigbeePrefixes)[number]; +import type { HttpResourceRef } from '@angular/common/http'; @Component({ selector: 'se-mqtt', imports: [ - PrettyJson, PowerMeterComponent, PairButtonComponent, StackedPerComponent, @@ -39,158 +42,235 @@ export type ZigbeePrefixes = (typeof zigbeePrefixes)[number]; templateUrl: './mqtt.component.html', styleUrl: './mqtt.component.css', changeDetection: ChangeDetectionStrategy.OnPush, - providers: [MqttService, ZigbeeService] + providers: [ZigbeeService] }) export class MqttComponent { - readonly #mqtt = inject(MqttService); readonly #z2m = inject(ZigbeeService); + readonly #settings = inject(MqttDeviceSettingsService); - readonly state = signal>({}); - readonly cleanState = computed(() => cleanUp(this.state())); - readonly filter = signal(undefined); - readonly devices = this.#z2m.devices; + readonly search = persistentSignal('mqttSearchFilters', { + searchText: '', + selectedPrefixes: ['e&m', 'kamp'], + booleanOptions: [ + { + name: 'allowPowerControl', + description: 'aan-uit schakelaar', + value: undefined + }, + { name: 'alertWhenOff', description: 'alert when off', value: undefined }, + { + name: 'alertWhenLost', + description: 'alert when lost', + value: undefined + }, + { name: 'isSubDevice', description: 'sub device', value: undefined } + ] + }); - readonly selectedPrefixes = persistentSignal( - 'defaultSelectedPrefixes', - ['e&m', 'kamp'] - ); + // Debounce the whole search object (text + boolean options) + readonly searchDebounced = debouncedComputed(this.search, { + delay: 200 + }); - readonly zigbeePrefixes = zigbeePrefixes; + setSearchText(v: string) { + this.search.update(current => ({ ...current, searchText: v })); + } - readonly selected = linkedSignal(() => { - const devices = this.devices(); - const filter = this.filter(); - if (!devices?.length) return undefined; - if (filter) { - const device = devices.find(d => d.definition?.model === filter); - if (device) return device.friendly_name || device.ieee_address; - } - return undefined; - }); + setBooleanOption(name: string, val?: boolean) { + this.search.update(current => ({ + ...current, + booleanOptions: current.booleanOptions.map(o => + o.name === name ? { ...o, value: val } : o + ) + })); + } - readonly deviceList = computed( - () => { - const devices = this.devices(); - return ( - devices - .map(device => ({ - name: device.friendly_name || device.ieee_address - })) - .sort((a, b) => a.name.localeCompare(b.name)) ?? [] - ); - }, - { equal: deepEqual } - ); + readonly selectedPrefixes = computed(() => this.search().selectedPrefixes); - readonly deviceTypes = computed( - () => - this.devices() - ?.reduce( - (acc, device) => { - const model = device.definition?.model || ''; - if (model && !acc.find(t => t[0] === model)) { - acc.push([model, device.definition?.description || '']); - } - return acc; - }, - [] as [string, string][] - ) - .sort() ?? [], - { equal: deepEqual } - ); + readonly zigbeePrefixes = zigbeePrefixes; - checkPf = (prefix: ZigbeePrefixes) => { - const current = this.selectedPrefixes(); - if (current.includes(prefix)) { - this.selectedPrefixes.set(current.filter(p => p !== prefix)); - } else { - this.selectedPrefixes.set([...current, prefix]); - } - }; + #matchesSelectedPrefix( + friendlyName: string | undefined, + selectedPrefixes: ZigbeePrefixes[] + ) { + if (selectedPrefixes.includes('Alles')) return true; + if (!friendlyName?.includes('/')) return true; + return selectedPrefixes.some(prefix => friendlyName.startsWith(prefix)); + } - _ = afterRenderEffect(() => { - this.powerUse(); // - }); + togglePrefixSelection = (prefix: ZigbeePrefixes) => { + this.search.update(current => { + const selectedPrefixes = current.selectedPrefixes.includes(prefix) + ? current.selectedPrefixes.filter(p => p !== prefix) + : [...current.selectedPrefixes, prefix]; + + return { ...current, selectedPrefixes }; + }); + }; readonly powerMeters = computed( () => - this.devices() + this.#z2m.devices() ?.filter(d => d.definition?.exposes?.some( e => e.property === 'power' && e.type === 'numeric' ) ) - .filter(d => - this.selectedPrefixes().includes('Alles') - ? true - : this.selectedPrefixes().some( - prefix => - d.friendly_name?.startsWith(prefix) || - !d.friendly_name?.includes('/') - ) - ) + .filter(d => !!d.ieee_address) .sort((a, b) => a.friendly_name.localeCompare(b.friendly_name)) ?? [] ); - devNames = computed(() => { - const result = this.powerMeters().map( - d => d.friendly_name || d.ieee_address - ); - return result; + // readonly deviceTypes = computed( + // () => + // this.devices() + // ?.reduce( + // (acc, device) => { + // const model = device.definition?.model || ''; + // if (model && !acc.find(t => t[0] === model)) { + // acc.push([model, device.definition?.description || '']); + // } + // return acc; + // }, + // [] as [string, string][] + // ) + // .sort() ?? [], + // { equal: deepEqual } + // ); + + readonly powerMetersFiltered = computed(() => { + const devices = this.devicesWithSettings() ?? []; + const searchState = this.searchDebounced(); + const searchText = (searchState.searchText ?? '') + .toString() + .trim() + .toLowerCase(); + const requiredBooleanOptions = (searchState.booleanOptions ?? []) + .filter(o => o.value === true) + .map(o => o.name); + + return devices.filter(device => { + const friendlyNameLower = String(device.friendly_name ?? '').toLowerCase(); + + if ( + !this.#matchesSelectedPrefix( + device.friendly_name, + searchState.selectedPrefixes + ) + ) + return false; + + if (requiredBooleanOptions.some(name => device.settings[name] !== true)) + return false; + + if (!searchText) return true; + return friendlyNameLower.includes(searchText); + }); }); - allStates = this.#z2m.getMultipleStatuses(this.devNames); + readonly deviceStatuses = this.#z2m.getMultipleStatuses( + computed(() => + this.powerMeters().map(d => d.friendly_name || (d.ieee_address as string)) + ) + ); + + // CouchDB http resource: batch_get request for all devices in `powerMeters`. + // Use `_bulk_get` with per-document `rev` where available so CouchDB can return specific revisions. + readonly deviceSettings: HttpResourceRef = + httpResource( + () => { + const keys = this.powerMeters() + .map(d => d.ieee_address) + .filter(Boolean) as string[]; + if (undefinedWhenEmpty(keys) === undefined) return undefined; + const list = this.#settings.list() ?? []; + if (undefinedWhenEmpty(list) === undefined) return undefined; + const docs = keys.map(k => { + const rev = list.find(i => i[0] === k)?.[1]; + return rev ? { id: k, rev } : { id: k }; + }); + return { + url: `${this.#settings.baseUrl()}/_bulk_get`, + method: 'POST', + body: { docs }, + credentials: 'include', + mode: 'cors' + } as any; + }, + { + injector: inject(Injector), + debugName: 'powerMetersBulkGet', + defaultValue: {}, + parse: (value: unknown): ParsedDeviceSettings => { + const response = value as BulkGetResponse; + const map: ParsedDeviceSettings = {}; + for (const r of response?.results ?? []) { + const id = r.id?.toString().toLowerCase(); + const ok = r.docs?.[0]?.ok as CouchDoc | undefined; + if (!id || !ok) continue; + map[id] = this.#settings.extractedOptions(ok); + } + return map; + } + } + ); + + // Combine runtime statuses with device settings (attach `settings` per device) + readonly devicesWithSettings = computed( + (): DeviceWithSetting[] => { + const devices = this.powerMeters(); + const statuses = (this.deviceStatuses.value() ?? []) as DeviceStatus[]; + const settingsById = this.deviceSettings.value() ?? {}; + const statusMapByFriendlyName = new Map(); + + for (const s of statuses) { + const name = s.friendly_name?.toLowerCase(); + if (name) statusMapByFriendlyName.set(name, s); + } + + return devices.map(device => { + const ieee = device.ieee_address.toLowerCase(); + const status = statusMapByFriendlyName.get( + device.friendly_name?.toLowerCase() + ); + const settings = settingsById[ieee] ?? this.#settings.defaultOptions; + + return { + friendly_name: + status?.friendly_name ?? + device.friendly_name ?? + device.ieee_address, + ieeeAddress: device.ieee_address, + power: status?.power ?? 0, + energy: status?.energy ?? 0, + current: status?.current ?? 0, + settings + } as DeviceWithSetting; + }); + }, + { equal: deepEqual } + ); - readonly powerUse = computed(() => { - const allStates = this.allStates.value() ?? []; + readonly powerUseByPrefix = computed(() => { + const selectedDevices = this.devicesWithSettings() ?? []; const result: Record< string, { power: number; energy: number; current: number } > = {}; - for (const state of allStates) { + for (const state of selectedDevices) { + if (state.settings?.isSubDevice) continue; // Skip sub-devices in aggregate calculations const prefix = extractPrefix(state.friendly_name); result[prefix] ??= { power: 0, energy: 0, current: 0 }; // Initialize with 0 - result[prefix].power += state.power || 0; - result[prefix].energy += state.energy || 0; - result[prefix].current += state.current || 0; + result[prefix].power += Math.round(state.power) || 0; + result[prefix].energy += Math.round(state.energy) || 0; + result[prefix].current += Math.round(state.current) || 0; } return result; - }); + }, { equal: deepEqual }); - readonly powerUsage = computed(() => { - const powerUse = this.powerUse(); - return Object.entries(powerUse).map(([prefix, usage]) => ({ + readonly powerUsage = computed(() => + Object.entries(this.powerUseByPrefix()).map(([prefix, usage]) => ({ name: prefix, value: usage.power - })); - }); - - readonly selectedDetails = computed(() => { - const devices = this.devices(); - const selected = this.selected(); - if (!selected) return undefined; - return devices?.find( - d => d.friendly_name === selected || d.ieee_address === selected - ); - }); - - readonly selectedDevice = rxResource({ - params: this.selected, - stream: args => { - const device = args.params; - if (!device) return EMPTY; - return this.#mqtt.listenFor(device); - } - }); -} - -const cleanUp = (obj: Record, path = ''): any => { - const { value, ...rest } = obj; - if (Object.keys(rest).length === 0) return value; - return Object.fromEntries( - Object.entries(obj).map(([key, val]) => { - // @ts-expect-error - return [key, typeof val === 'object' ? cleanUp(val) : val]; - }) + })) ); -}; +} diff --git a/src/app/mqtt/mqtt.component.types.ts b/src/app/mqtt/mqtt.component.types.ts new file mode 100644 index 00000000..b850fbc3 --- /dev/null +++ b/src/app/mqtt/mqtt.component.types.ts @@ -0,0 +1,51 @@ +import type { + MqttDeviceOptions, + MqttDeviceSetting +} from './mqtt-device-settings.types'; +import type { ZigbeePrefixes } from './zigbee-prefixes.types'; + +export type CouchDoc = MqttDeviceSetting & { _id?: string; _rev?: string }; + +export interface BulkGetDoc { + ok?: CouchDoc; + missing?: boolean; + error?: { id?: string; rev?: string; reason?: string } | any; +} + +export interface BulkGetResult { + id: string; + docs: BulkGetDoc[]; +} + +export type BulkGetResponse = { results?: BulkGetResult[] }; +export type ParsedDeviceSettings = Record; + +export interface DeviceStatus { + friendly_name: string; + ieeeAddress: string; + power: number; + energy: number; + current: number; +} + +export interface DeviceWithSetting extends DeviceStatus { + settings: MqttDeviceOptions; +} + +export type SearchBooleanOptionName = + | 'allowPowerControl' + | 'alertWhenOff' + | 'alertWhenLost' + | 'isSubDevice'; + +export interface SearchBooleanOption { + name: SearchBooleanOptionName; + description?: string; + value?: boolean | undefined; +} + +export interface SearchState { + searchText: string; + selectedPrefixes: ZigbeePrefixes[]; + booleanOptions: SearchBooleanOption[]; +} diff --git a/src/app/mqtt/mqtt.service.ts b/src/app/mqtt/mqtt.service.ts index c1d03db0..89ee7d22 100644 --- a/src/app/mqtt/mqtt.service.ts +++ b/src/app/mqtt/mqtt.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable, PLATFORM_ID } from '@angular/core'; import { deepEqual } from '@se-ng/signal-utils'; import type { OnMessageCallback } from 'mqtt'; import { @@ -15,10 +15,12 @@ import { timer } from 'rxjs'; -import type { MqttMessage } from './mqtt.types'; +import { isPlatformBrowser } from '@angular/common'; +import type { MqttMessage } from './mqtt.service.types'; @Injectable({ providedIn: 'root' }) export class MqttService { + #isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); mqtt = import('mqtt'); client = this.mqtt.then(m => m.default.connectAsync(`wss://mqtt.eliasweb.nl`) @@ -26,29 +28,31 @@ export class MqttService { /** base topic */ readonly baseTopic = 'zigbee2mqtt'; messages$ = new Observable(subscriber => { - const cb: OnMessageCallback = (topic, message): void => { - try { - subscriber.next({ topic, message: JSON.parse(message.toString()) }); - } catch (e) { - subscriber.next({ topic, message: message.toString() }); - } - }; + if (this.#isBrowser) { + const cb: OnMessageCallback = (topic, message): void => { + try { + subscriber.next({ topic, message: JSON.parse(message.toString()) }); + } catch (e) { + subscriber.next({ topic, message: message.toString() }); + } + }; - this.client.then(client => { - console.log('start listening for MQTT messages'); - client.on('message', cb); - client.on('error', err => { - console.error('MQTT client error', err); - subscriber.error(err); - }); - }); - return () => { this.client.then(client => { - client.off('message', cb); - client.end(); //disconnect from the MQTT broker - console.log('MQTT client disconnected'); + console.log('start listening for MQTT messages'); + client.on('message', cb); + client.on('error', err => { + console.error('MQTT client error', err); + subscriber.error(err); + }); }); - }; + return () => { + this.client.then(client => { + client.off('message', cb); + client.end(); //disconnect from the MQTT broker + console.log('MQTT client disconnected'); + }); + }; + } }).pipe( share({ connector: () => new Subject(), diff --git a/src/app/mqtt/mqtt.service.types.ts b/src/app/mqtt/mqtt.service.types.ts new file mode 100644 index 00000000..0f5c6b7a --- /dev/null +++ b/src/app/mqtt/mqtt.service.types.ts @@ -0,0 +1,4 @@ +export interface MqttMessage { + topic: string; + message: string; +} diff --git a/src/app/mqtt/mqtt.types.ts b/src/app/mqtt/mqtt.types.ts index dacb7bdf..271052bf 100644 --- a/src/app/mqtt/mqtt.types.ts +++ b/src/app/mqtt/mqtt.types.ts @@ -1,13 +1,6 @@ -// Types and interfaces moved from mqtt.service.ts - -export interface MqttMessage { - topic: string; - message: string; -} - export interface Z2MDevice { disabled: boolean; - endpoints: { [key: string]: Endpoint }; + endpoints: Record; friendly_name: string; ieee_address: string; interview_completed: boolean; @@ -69,7 +62,7 @@ export interface ExposeFeature { value_toggle?: ValueToggle; value_max?: number; value_min?: number; - presets?: PurplePreset[]; + presets?: NumericPreset[]; unit?: string; features?: Option[]; } @@ -92,26 +85,26 @@ export interface Option { export interface OptionFeature { access: number; - description: FeatureDescription; - label: Label; - name: PropertyEnum; - property: PropertyEnum; + description: OptionFeatureDescription; + label: OptionFeatureLabel; + name: OptionFeatureProperty; + property: OptionFeatureProperty; type: FeatureType; value_min: number; unit?: string; } -export enum FeatureDescription { +export enum OptionFeatureDescription { DeltaPerInterval20ByDefault = 'Delta per interval, 20 by default', IntervalDuration = 'Interval duration' } -export enum Label { +export enum OptionFeatureLabel { Delta = 'Delta', Interval = 'Interval' } -export enum PropertyEnum { +export enum OptionFeatureProperty { Delta = 'delta', Interval = 'interval' } @@ -135,8 +128,8 @@ export interface ItemType { export interface OptionPreset { description: PresetDescription; - name: ValueEnum; - value: ValueEnum; + name: PresetValue; + value: PresetValue; } export enum PresetDescription { @@ -144,12 +137,12 @@ export enum PresetDescription { UsePreviousValue = 'Use previous value' } -export enum ValueEnum { +export enum PresetValue { Minimum = 'minimum', Previous = 'previous' } -export interface PurplePreset { +export interface NumericPreset { description: string; name: string; value: number; @@ -177,7 +170,7 @@ export interface Endpoint { bindings: Binding[]; clusters: Clusters; configured_reportings: ConfiguredReporting[]; - scenes: any[]; + scenes: unknown[]; } export interface Binding { @@ -187,12 +180,12 @@ export interface Binding { export interface Target { endpoint?: number; - ieee_address?: IEEEAddress; + ieee_address?: IeeeAddress; type: TargetType; id?: number; } -export enum IEEEAddress { +export enum IeeeAddress { The0Xccccccfffe8A8966 = '0xccccccfffe8a8966', The0Xe0798Dfffebc6E5D = '0xe0798dfffebc6e5d' } @@ -236,3 +229,4 @@ export enum Z2MDeviceType { EndDevice = 'EndDevice', Router = 'Router' } + diff --git a/src/app/mqtt/pair-button/pair-button.component.ts b/src/app/mqtt/pair-button/pair-button.component.ts index 72d3c9cc..b8e40f90 100644 --- a/src/app/mqtt/pair-button/pair-button.component.ts +++ b/src/app/mqtt/pair-button/pair-button.component.ts @@ -13,7 +13,7 @@ import { import { toObservable, toSignal } from '@angular/core/rxjs-interop'; import { filter, interval, map, startWith, switchMap, takeWhile } from 'rxjs'; -import type { ZigbeePrefixes } from '../mqtt.component'; +import type { ZigbeePrefixes } from '../zigbee-prefixes.types'; import { ZigbeeService } from '../zigbee.service'; @Component({ diff --git a/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.css b/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.css index 2b5e7f12..40d021af 100644 --- a/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.css +++ b/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.css @@ -1,5 +1,11 @@ :host { - display: block; + display: flex; +} + +form { + display: flex; + flex-direction: column; + gap: var(--size-4); } label { @@ -7,7 +13,14 @@ label { display: grid; grid-template-columns: 5rem 1fr auto; align-items: center; - gap: 0.5rem; + gap: var(--size-1); + + &:has([type='checkbox']) { + grid-template-columns: auto 1fr auto; + input { + justify-self: end;; + } + } } svg { diff --git a/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.ts b/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.ts index 1c1e27c6..2cd81c5a 100644 --- a/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.ts +++ b/src/app/mqtt/power-meter/dialog/power-meter-dialog.component.ts @@ -14,11 +14,9 @@ import { import { form, FormField, FormRoot } from '@angular/forms/signals'; import { deepEqual } from '@se-ng/signal-utils'; -import { - MqttDeviceSettingsService, - type MqttDeviceOptions -} from '../../mqtt-device-settings.service'; -import { zigbeePrefixes } from '../../mqtt.component'; +import { MqttDeviceSettingsService } from '../../mqtt-device-settings.service'; +import type { MqttDeviceOptions } from '../../mqtt-device-settings.types'; +import { zigbeePrefixes } from '../../zigbee-prefixes.types'; import { ZigbeeService } from '../../zigbee.service'; import { splitName } from './split-name'; @@ -118,39 +116,17 @@ export class PowerMeterDialogComponent { protected readonly settings = inject(MqttDeviceSettingsService); readonly ieeeAddress = input.required(); protected readonly deviceSettings = this.settings.read(this.ieeeAddress); + protected readonly deviceOptions = this.settings.optionsFromDevResource(this.deviceSettings); readonly customGroup = signal(false); readonly zigbeePrefixes = zigbeePrefixes.filter(p => p !== 'Alles'); - readonly subGroups = computed( - () => { - const list = this.z2m.devices().map(d => d.friendly_name.split('/')); - const subGroups: Record = {}; - for (const dev of list) { - if (dev.length <= 2) continue; - const prefix = dev[0] as 'e&m' | 's&m' | 'zaak' | 'kamp'; - const subGroup = dev[1]; - if (!this.zigbeePrefixes.includes(prefix) || !subGroup) continue; - subGroups[prefix] ??= []; - if (!subGroups[prefix].includes(subGroup)) { - subGroups[prefix].push(subGroup); - } - } - return subGroups; - }, - { debugName: 'SubGroups', equal: deepEqual } - ); + readonly subGroups = this.z2m.deviceSubgroups; model = linkedSignal(() => { - const options: MqttDeviceOptions = this.deviceSettings.hasValue() - ? this.deviceSettings.value() - : {}; return { ...splitName(this.baseName()), - isSubDevice: options.isSubDevice || false, - allowPowerControl: options.allowPowerControl || false, - alertWhenLost: options.alertWhenLost || false, - alertWhenOff: options.alertWhenOff || false + ...this.deviceOptions(), }; }); @@ -164,7 +140,9 @@ export class PowerMeterDialogComponent { fd = form(this.model, () => undefined, { submission: { action: async value => { + const currentValue = this.model(); if (this.baseName() !== this.newName()) { + // update the name in the zigbee setup. const result = await this.z2m.publish( 'zigbee2mqtt/bridge/request/device/rename', { @@ -175,6 +153,15 @@ export class PowerMeterDialogComponent { ); console.log({ result }); } + await this.settings.update({ + id: this.ieeeAddress(), + friendlyName: this.newName(), + alertWhenLost: currentValue.alertWhenLost, + alertWhenOff: currentValue.alertWhenOff, + allowPowerControl: currentValue.allowPowerControl, + isSubDevice: currentValue.isSubDevice, + maxPower: this.deviceSettings.value()?.maxPower || 0 + }); this.closeDialog(); } } diff --git a/src/app/mqtt/power-meter/power-meter.component.ts b/src/app/mqtt/power-meter/power-meter.component.ts index 6a054326..90f0a856 100644 --- a/src/app/mqtt/power-meter/power-meter.component.ts +++ b/src/app/mqtt/power-meter/power-meter.component.ts @@ -1,27 +1,25 @@ import { afterNextRender, afterRenderEffect, + ChangeDetectionStrategy, Component, computed, inject, input, + linkedSignal, signal, - type WritableSignal, - ChangeDetectionStrategy + type WritableSignal } from '@angular/core'; import { GaugeComponent } from '../../metered-view/gauge/gauge.component'; -import { type ZigbeePrefixes, zigbeePrefixes } from '../mqtt.component'; +import { zigbeePrefixes, type ZigbeePrefixes } from '../zigbee-prefixes.types'; import { ToggleComponent } from '../toggle/toggle.component'; -import { persistentLinkedSignal } from '../util/idbstorage'; import { ZigbeeService } from '../zigbee.service'; +import { MqttDeviceSettingsService } from '../mqtt-device-settings.service'; +import type { MqttDeviceSetting } from '../mqtt-device-settings.types'; import { PowerMeterDialogComponent } from './dialog/power-meter-dialog.component'; import { splitName } from './dialog/split-name'; -import { - MqttDeviceSettingsService, - type MqttDeviceSetting -} from '../mqtt-device-settings.service'; @Component({ selector: 'power-meter', @@ -61,7 +59,7 @@ import { Loading...
} - @if (!name().includes('Computer')) { + @if (options().allowPowerControl) { } @@ -77,16 +75,13 @@ export class PowerMeterComponent { protected readonly setting = inject(MqttDeviceSettingsService); readonly dialogOpen = signal(false, { debugName: 'PowerMeterDialogOpen' }); - readonly options = this.setting.read(this.ieeeAddress); + readonly optionsRef = this.setting.read(this.ieeeAddress); + readonly options = this.setting.optionsFromDevResource(this.optionsRef); readonly __ = afterRenderEffect(async () => { if (this.ieeeAddress() === 'unknown' || !this.ieeeAddress()) return; const splitName = this.splitName(); - const currentPower = this.currentPower(); if (!splitName.name) return; - if (currentPower > this.maxUsedPower()) { - this.maxUsedPower.set(currentPower); - } - const notFound = this.options.error()?.['status'] === 404; + const notFound = this.optionsRef.error()?.['status'] === 404; if (notFound) { console.log('not found, creating default setting'); await this.setting.create({ @@ -96,13 +91,13 @@ export class PowerMeterComponent { }); return; } - if (this.options.hasValue()) { - const opt = this.options.value() as MqttDeviceSetting; + if (this.optionsRef.hasValue()) { + const opt = this.optionsRef.value() as MqttDeviceSetting; + if (!opt?.id) return; if ( - opt.friendlyName !== this.friendlyName() || - (opt.maxPower || 0) < this.maxUsedPower() + opt.friendlyName !== this.friendlyName() || // update friendly name if it has changed + (opt.maxPower || 0) < this.maxUsedPower() // update max power if current max is higher than stored max ) { - console.log('friendly name changed, updating setting'); await this.setting.update({ ...opt, friendlyName: this.friendlyName(), @@ -110,7 +105,6 @@ export class PowerMeterComponent { }); } } - // console.log(this.options.hasValue() && this.options.value()); }); readonly #deviceResource = this.z2m.getDeviceStatus(this.ieeeAddress); @@ -123,8 +117,11 @@ export class PowerMeterComponent { debugName: 'CurrentPower' } ); - maxUsedPower: WritableSignal = signal(0, { - debugName: 'MaxUsedPower' + maxUsedPower: WritableSignal = linkedSignal(() => { + const optionsMax = this.optionsRef.hasValue() + ? this.optionsRef.value()?.maxPower || 0 + : 0; + return Math.max(optionsMax, this.currentPower() || 0); }); readonly friendlyName = computed( () => this.#deviceInfo()?.friendly_name || this.ieeeAddress() @@ -145,8 +142,23 @@ export class PowerMeterComponent { }; readonly _ = afterNextRender(() => { + let tries = 0; + const randomDelay = () => Math.random() * 2000 + 1500; // 1500ms to 3500ms + const attemptRefresh = () => { + if (tries >= 15) { + console.log(`Max refresh attempts reached for ${this.name()}. Giving up.`); + return; // Give up after 5 tries + } + if (!this.deviceLoading()) { + return; + } + tries++; + this.refresh(); + // console.log(`Attempt ${tries}: Refreshing device status for ${this.name()}`); + setTimeout(attemptRefresh, randomDelay()); + }; // trigger initial state fetch - this.refresh(); + attemptRefresh(); }); } diff --git a/src/app/mqtt/zigbee-prefixes.types.ts b/src/app/mqtt/zigbee-prefixes.types.ts new file mode 100644 index 00000000..cb27ef51 --- /dev/null +++ b/src/app/mqtt/zigbee-prefixes.types.ts @@ -0,0 +1,6 @@ +export const zigbeePrefixes = ['e&m', 's&m', 'zaak', 'kamp', 'Alles'] as const; + +export type ZigbeePrefix = (typeof zigbeePrefixes)[number]; + +// Backward-compatible alias. +export type ZigbeePrefixes = ZigbeePrefix; diff --git a/src/app/mqtt/zigbee.service.ts b/src/app/mqtt/zigbee.service.ts index adc366a3..55a168e0 100644 --- a/src/app/mqtt/zigbee.service.ts +++ b/src/app/mqtt/zigbee.service.ts @@ -15,12 +15,14 @@ import { import { MqttService } from './mqtt.service'; import type { Z2MDevice } from './mqtt.types'; +import { MqttDeviceSettingsService } from './mqtt-device-settings.service'; @Injectable({ providedIn: 'root' }) export class ZigbeeService { mqtt = inject(MqttService); + #settings = inject(MqttDeviceSettingsService); injector = inject(Injector); devices: Signal = toSignal( @@ -28,6 +30,29 @@ export class ZigbeeService { { initialValue: [], debugName: 'ZigbeeServiceDevices' } ) as Signal; + deviceSubgroups = computed( + () => { + const list = this.devices().map(d => d.friendly_name.split('/')); + const subGroups: Record = {}; + for (const dev of list) { + if (dev.length <= 2) continue; + const prefix = dev[0].toLowerCase() as 'e&m' | 's&m' | 'zaak' | 'kamp'; + const subGroup = dev[1]; + if (!subGroup) continue; + subGroups[prefix] ??= []; + if (!subGroups[prefix].includes(subGroup)) { + subGroups[prefix].push(subGroup); + subGroups[prefix] = [ + ...subGroups[prefix].sort((a, b) => a.localeCompare(b)) + ]; + } + } + // console.log(JSON.stringify({ subGroups }, null, 2)); + return subGroups; + }, + { debugName: 'DeviceSubGroups', equal: deepEqual } + ); + getDeviceInfo = (ieeeAddress: Signal) => computed(() => this.#getDevice(ieeeAddress()), { equal: deepEqual }); @@ -67,9 +92,10 @@ export class ZigbeeService { map(statuses => { return statuses.map((status, index) => { if (typeof status !== 'object' || status === null) { - // console.warn(`Invalid status for topic ${params[index]}:`, status); + console.warn(`Invalid status for topic ${params[index]}:`, status); return { friendly_name: params[index], + ieeeAddress: '', power: 0, energy: 0, current: 0 @@ -77,6 +103,7 @@ export class ZigbeeService { } else { return { friendly_name: params[index], + ieeeAddress: status['ieee_address'] ?? '', power: status['power'] ?? 0, energy: status['energy'] ?? 0, current: status['current'] ?? 0 diff --git a/src/bootspa.ts b/src/bootspa.ts index a5464079..788440d1 100644 --- a/src/bootspa.ts +++ b/src/bootspa.ts @@ -13,7 +13,7 @@ library.add(faPlay as any, faPause as any); dom.watch(); if (environment.production) { - enableProdMode(); + // enableProdMode(); } else { // // @ts-expect-error // setTimeout(() => ng.enableProfiling(), 0); diff --git a/tsconfig.json b/tsconfig.json index 63025aef..9545a81f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "compileOnSave": false, "compilerOptions": { - "baseUrl": "./", "outDir": "./dist/out-tsc", "sourceMap": true, "esModuleInterop": true, @@ -18,18 +17,19 @@ "lib": ["esNext", "dom"], "types": ["node", "@types/wicg-file-system-access"], "paths": { - "@se-ng/headless-ui": ["dist/se-ng/headless-ui"], - "@se-ng/headless-ui/*": ["dist/se-ng/headless-ui/*"], - "@se-ng/observable-hooks": ["dist/se-ng/observable-hooks"], - "@se-ng/observable-hooks/*": ["dist/se-ng/observable-hooks/*"], - "@se-ng/swapi": ["dist/se-ng/swapi"], - "@se-ng/swapi/*": ["dist/se-ng/swapi/*"], - "@se-ng/observable-utils": ["dist/se-ng/observable-utils"], - "@se-ng/observable-utils/*": ["dist/se-ng/observable-utils/*"], - "@se-ng/signal-utils": ["dist/se-ng/signal-utils"], - "@se-ng/signal-utils/*": ["dist/se-ng/signal-utils/*"], - "@se-ng/let": ["dist/se-ng/let"], - "@se-ng/let/*": ["dist/se-ng/let/*"] + "src/*": ["./src/*"], + "@se-ng/headless-ui": ["./dist/se-ng/headless-ui"], + "@se-ng/headless-ui/*": ["./dist/se-ng/headless-ui/*"], + "@se-ng/observable-hooks": ["./dist/se-ng/observable-hooks"], + "@se-ng/observable-hooks/*": ["./dist/se-ng/observable-hooks/*"], + "@se-ng/swapi": ["./dist/se-ng/swapi"], + "@se-ng/swapi/*": ["./dist/se-ng/swapi/*"], + "@se-ng/observable-utils": ["./dist/se-ng/observable-utils"], + "@se-ng/observable-utils/*": ["./dist/se-ng/observable-utils/*"], + "@se-ng/signal-utils": ["./dist/se-ng/signal-utils"], + "@se-ng/signal-utils/*": ["./dist/se-ng/signal-utils/*"], + "@se-ng/let": ["./dist/se-ng/let"], + "@se-ng/let/*": ["./dist/se-ng/let/*"] }, "useDefineForClassFields": false },