diff --git a/.all-contributorsrc b/.all-contributorsrc index 0079dd719..6e8d23087 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -29,6 +29,10 @@ "translation-ru": { "symbol": "🇷🇺", "description": "Translate in Russian" + }, + "translation-ch": { + "symbol": "🇨🇳", + "description": "Translate in Chinese" } }, "contributors": [ @@ -100,6 +104,34 @@ "challenge" ] }, + { + "login": "alcaidio", + "name": "Timothy Alcaide", + "avatar_url": "https://avatars.githubusercontent.com/u/17033036?v=4", + "profile": "https://twitter.com/alcaidio", + "contributions": [ + "challenge" + ] + }, + { + "login": "LMFinney", + "name": "Lance Finney", + "avatar_url": "https://avatars.githubusercontent.com/u/6683747?v=4", + "profile": "https://github.com/LMFinney", + "contributions": [ + "doc", + "challenge" + ] + }, + { + "login": "tsironis13", + "name": "Tsironis Ioannis", + "avatar_url": "https://avatars.githubusercontent.com/u/7561447?v=4", + "profile": "https://github.com/tsironis13", + "contributions": [ + "challenge" + ] + }, { "login": "alan-bio", "name": "Alan Dragicevich", @@ -240,6 +272,106 @@ "contributions": [ "translation-ru" ] + }, + { + "login": "vimulatus", + "name": "Vimulatus", + "avatar_url": "https://avatars.githubusercontent.com/u/63696128?v=4", + "profile": "https://github.com/vimulatus", + "contributions": [ + "doc" + ] + }, + { + "login": "alannelucq", + "name": "Arthur LANNELUCQ", + "avatar_url": "https://avatars.githubusercontent.com/u/44091408?v=4", + "profile": "https://github.com/alannelucq", + "contributions": [ + "translation-fr" + ] + }, + { + "login": "fixedmichal", + "name": "fixed_michal", + "avatar_url": "https://avatars.githubusercontent.com/u/26270192?v=4", + "profile": "https://github.com/fixedmichal", + "contributions": [ + "bug" + ] + }, + { + "login": "Tenessy", + "name": "Tenessy", + "avatar_url": "https://avatars.githubusercontent.com/u/65855673?v=4", + "profile": "https://github.com/Tenessy", + "contributions": [ + "bug" + ] + }, + { + "login": "EnochGao", + "name": "Enoch Gao", + "avatar_url": "https://avatars.githubusercontent.com/u/41459067?v=4", + "profile": "https://enochgao.github.io/", + "contributions": [ + "doc", + "translation-ch" + ] + }, + { + "login": "fpalmab", + "name": "Francisco Palma", + "avatar_url": "https://avatars.githubusercontent.com/u/7729812?v=4", + "profile": "https://github.com/fpalmab", + "contributions": [ + "bug" + ] + }, + { + "login": "michalgrzegorczyk-dev", + "name": "Michał Grzegorczyk", + "avatar_url": "https://avatars.githubusercontent.com/u/47832176?v=4", + "profile": "https://github.com/michalgrzegorczyk-dev", + "contributions": [ + "doc" + ] + }, + { + "login": "tamim36", + "name": "Tamim Arefin Anik", + "avatar_url": "https://avatars.githubusercontent.com/u/42251521?v=4", + "profile": "https://github.com/tamim36", + "contributions": [ + "bug" + ] + }, + { + "login": "WhoisBsa", + "name": "Matheus B.", + "avatar_url": "https://avatars.githubusercontent.com/u/36895235?v=4", + "profile": "https://github.com/WhoisBsa", + "contributions": [ + "bug" + ] + }, + { + "login": "StefH", + "name": "Stef Heyenrath", + "avatar_url": "https://avatars.githubusercontent.com/u/249938?v=4", + "profile": "https://sourcerer.io/stefh", + "contributions": [ + "doc" + ] + }, + { + "login": "mathisvester", + "name": "mathisvester", + "avatar_url": "https://avatars.githubusercontent.com/u/26164587?v=4", + "profile": "https://github.com/mathisvester", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/.eslintrc.json b/.eslintrc.json index c222fb084..de9b234b6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,6 +6,7 @@ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": { + "@angular-eslint/no-host-metadata-property": "off", "@nx/enforce-module-boundaries": [ "error", { @@ -18,24 +19,24 @@ } ] } - ], - "@angular-eslint/no-host-metadata-property": [ - "error", - { - "allowStatic": true - } ] } }, { "files": ["*.ts", "*.tsx"], "extends": ["plugin:@nx/typescript"], - "rules": {} + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off" + } }, { "files": ["*.js", "*.jsx"], "extends": ["plugin:@nx/javascript"], - "rules": {} + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off" + } }, { "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], diff --git a/.github/copilot-guidelines.md b/.github/copilot-guidelines.md new file mode 100644 index 000000000..e1b11d43a --- /dev/null +++ b/.github/copilot-guidelines.md @@ -0,0 +1,46 @@ +# GitHub Copilot Custom Guidelines + +You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. + +## TypeScript Best Practices + +- Use strict type checking +- Prefer type inference when the type is obvious +- Avoid the `any` type; use `unknown` when type is uncertain + +## Angular Best Practices + +- Always use standalone components over NgModules +- Don't use explicit `standalone: true` (it is implied by default) +- Use signals for state management +- Implement lazy loading for feature routes +- Use `NgOptimizedImage` for all static images. + +## Components + +- Keep components small and focused on a single responsibility +- Use `input()` and `output()` functions instead of decorators +- Use `computed()` for derived state +- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator +- Prefer inline templates for small components +- Prefer Reactive forms instead of Template-driven ones +- Do NOT use `ngClass`, use `class` bindings instead +- DO NOT use `ngStyle`, use `style` bindings instead + +## State Management + +- Use signals for local component state +- Use `computed()` for derived state +- Keep state transformations pure and predictable + +## Templates + +- Keep templates simple and avoid complex logic +- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` +- Use the async pipe to handle observables + +## Services + +- Design services around a single responsibility +- Use the `providedIn: 'root'` option for singleton services +- Use the `inject()` function instead of constructor injection diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 000000000..f1327048f --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1 @@ +github: [tomalaforge] diff --git a/.github/github-action/action.yml b/.github/github-action/action.yml new file mode 100644 index 000000000..8019592af --- /dev/null +++ b/.github/github-action/action.yml @@ -0,0 +1,14 @@ +name: 'Hello World' +description: 'Greet someone and record the time' +inputs: + github_token: + description: A GitHub token. + required: false + default: ${{ github.token }} + repo: + description: The owner and repository name. + required: false + default: ${{ github.repository }} +runs: + using: 'node20' + main: 'index.js' diff --git a/.github/github-action/contributors.js b/.github/github-action/contributors.js new file mode 100644 index 000000000..a8f1bcaa6 --- /dev/null +++ b/.github/github-action/contributors.js @@ -0,0 +1,37 @@ +const contributors = [ + 'alcaidio', + 'svenson95', + 'jdegand', + 'DeveshChau', + 'stillst', + 'wandri', + 'webbomj', + 'kabrunko-dev', + 'Sanjar1304', + 'tsironis13', + 'EnochGao', +]; + +const sponsors = [ + 'ddotx', + 'LMFinney', + 'alannelucq', + 'SidV2', + 'fpalmab', + 'CivilEngeneer', + 'apalaio', + 'amosISA', + 'michalgrzegorczyk-dev', + 'zealotrahl', + 'DzoeL123', + 'allan1989', + 'pchessah', + 'lukasss88', + 'danncortes', + 'Gw0zdziu' +]; + +module.exports = { + contributors, + sponsors, +}; diff --git a/.github/github-action/index.js b/.github/github-action/index.js new file mode 100644 index 000000000..a73e6c293 --- /dev/null +++ b/.github/github-action/index.js @@ -0,0 +1,45 @@ +const github = require('@actions/github'); +const core = require('@actions/core'); +const { contributors, sponsors } = require('./contributors'); + +async function run() { + try { + const title = github.context.payload.pull_request.title; + const labels = ['answer']; + + const match = title.match(/Answer(:?)\s*(\d+)/); + if (match) { + labels.push(String(parseInt(match[2], 10))); + } + + const actor = github.context.actor; + if (contributors.includes(actor)) { + labels.push('contributor'); + labels.push('to be reviewed'); + } + + if (sponsors.includes(actor)) { + labels.push('sponsor'); + labels.push('to be reviewed'); + } + + const githubToken = core.getInput('github_token'); + + const number = github.context.payload.pull_request.number; + + const octokit = github.getOctokit(githubToken); + await octokit.rest.issues.addLabels({ + labels, + owner: github.context.repo.owner, + repo: github.context.repo.repo, + issue_number: number, + }); + } catch (e) { + if (e instanceof Error) { + core.error(e); + core.setFailed(e.message); + } + } +} + +run(); diff --git a/.github/workflows/close-inactive-pr.yml b/.github/workflows/close-inactive-pr.yml index d92c25cdb..d5e0e9c95 100644 --- a/.github/workflows/close-inactive-pr.yml +++ b/.github/workflows/close-inactive-pr.yml @@ -1,7 +1,7 @@ name: Close inactive issues on: schedule: - - cron: '20 1 * * *' + - cron: '0 0 * * *' jobs: close-issues: @@ -10,18 +10,19 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@v5 + - uses: actions/stale@v9 with: days-before-issue-stale: 20 days-before-issue-close: -1 stale-issue-label: 'stale' - stale-issue-message: 'This issue is stale because it has been open for 20 days with no activity.' + stale-issue-message: 'This issue is stale because it has been open for 15 days with no activity.' exempt-issue-labels: 'long-term' days-before-pr-stale: 20 days-before-pr-close: 7 stale-pr-label: 'stale' - stale-pr-message: 'This pull request is stale because it has been open for 20 days with no activity.' - close-pr-message: 'This pull request was closed because it has been inactive for 7 days since being marked as stale.' + stale-pr-message: 'This pull request is stale because it has been open for 15 days with no activity.' + close-pr-message: 'This pull request was closed because it has been inactive for 5 days since being marked as stale.' only-pr-labels: 'answer' - exempt-pr-labels: 'challenge-creation, long-term' + exempt-pr-labels: 'challenge-creation, long-term, to be reviewed' + remove-pr-stale-when-updated: true repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/label-issue-update.yml b/.github/workflows/label-issue-update.yml new file mode 100644 index 000000000..5f79b0568 --- /dev/null +++ b/.github/workflows/label-issue-update.yml @@ -0,0 +1,21 @@ +name: updates Labels + +on: + push: + branches-ignore: + - main + +jobs: + update_labels: + runs-on: ubuntu-latest + if: | + contains(github.event.pull_request.labels.*.name, 'sponsor') || + contains(github.event.pull_request.labels.*.name, 'contributor') + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Add labels + uses: actions-ecosystem/action-add-labels@v1 + with: + labels: to be reviewed/update diff --git a/.github/workflows/label-issue.yml b/.github/workflows/label-issue.yml index 5c621375d..a5fd40632 100644 --- a/.github/workflows/label-issue.yml +++ b/.github/workflows/label-issue.yml @@ -1,29 +1,37 @@ name: Add Labels on: - pull_request: + pull_request_target: types: [ opened, edited, synchronize ] jobs: - add_supporters: + check-title: runs-on: ubuntu-latest steps: - - name: checkout - uses: actions/checkout@v2 - - - name: add labels - uses: actions-ecosystem/action-add-labels@v1 - if: ${{ contains( fromJson('[ "tomalaforge", "alcaidio" , "svenson95", "jdegand", "DeveshChau", "stillst", "wandri", "webbomj", "kabrunko-dev", "Sanjar1304"]'), github.actor ) && startsWith(github.event.pull_request.title, 'Answer') }} - with: - labels: supporter - add_answers: + - name: Check PR title + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + echo "Checking PR Title: '$PR_TITLE'" + if [[ ! "$PR_TITLE" =~ ^Answer: ]]; then + echo "❌ PR title should start with 'Answer:[#challenge number]'" + echo "### ❌ PR title should start with 'Answer:[#challenge number]'" >> $GITHUB_STEP_SUMMARY + exit 1 + else + echo "✅ PR title format is correct." + echo "### ✅ PR title format is correct." >> $GITHUB_STEP_SUMMARY + fi + add_labels: runs-on: ubuntu-latest + if: ${{ startsWith(github.event.pull_request.title, 'Answer') }} steps: - name: checkout uses: actions/checkout@v2 - - name: add labels - uses: actions-ecosystem/action-add-labels@v1 - if: ${{ startsWith(github.event.pull_request.title, 'Answer') }} + - name: Install dependencies + run: npm i @actions/core @actions/github + + - name: Add labels + uses: ./.github/github-action/ with: - labels: answer + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 5472d6bdf..8fb71de22 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,13 @@ Thumbs.db TODO.md .nx/cache +.nx/workspace-data + +.cursorrules +.cursor/rules/nx-rules.mdc +.github/instructions/nx.instructions.md + +package-lock.json +npm-shrinkwrap.json + +__screenshots__/ diff --git a/.prettierignore b/.prettierignore index ab639d33d..a4684ea74 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,4 +5,5 @@ .angular -/.nx/cache \ No newline at end of file +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/README.md b/README.md index b516e561b..f3802e918 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@
+> [!WARNING] +> This project now uses **pnpm** as its package manager. Please make sure you have pnpm installed before running any commands. You can install it globally with `npm install -g pnpm` or follow the [official installation guide](https://pnpm.io/installation). + +
+ ## Intro This project has been created with three purposes: @@ -24,7 +29,7 @@ If you would like to propose a challenge, this project is open source, so feel f ## Challenges -Check [all 47 challenges](https://angular-challenges.vercel.app/) +Check [all 61 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ @@ -40,25 +45,42 @@ Check [all 47 challenges](https://angular-challenges.vercel.app/) Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩 stillst
stillst

🧩 🇷🇺 Wandrille
Wandrille

🧩 - Alan Dragicevich
Alan Dragicevich

📖 + Timothy Alcaide
Timothy Alcaide

🧩 + Lance Finney
Lance Finney

📖 🧩 + Tsironis Ioannis
Tsironis Ioannis

🧩 + Alan Dragicevich
Alan Dragicevich

📖 Michel EDIGHOFFER
Michel EDIGHOFFER

📖 Gerardo Sebastian Gonzalez
Gerardo Sebastian Gonzalez

📖 Evseev Yuriy
Evseev Yuriy

🐛 Tomer953
Tomer953

🐛 📖 💻 + + Dmitriy Mishchenko
Dmitriy Mishchenko

📖 Sagar Devkota
Sagar Devkota

📖 💻 Nelson Gutierrez
Nelson Gutierrez

🇪🇸 - - Hossain K. M.
Hossain K. M.

📖 Diogo Nishikawa
Diogo Nishikawa

💻 🇵🇹 📖 Erick Rodriguez
Erick Rodriguez

🇪🇸 Eduardo Roth
Eduardo Roth

📖 🇪🇸 + + Fernando Bello
Fernando Bello

📖 Лапин Андрей (Lapin Andrey)
Лапин Андрей (Lapin Andrey)

🇷🇺 Dinar Shagaliev
Dinar Shagaliev

🇷🇺 + Vimulatus
Vimulatus

📖 + Arthur LANNELUCQ
Arthur LANNELUCQ

🇫🇷 + fixed_michal
fixed_michal

🐛 + Tenessy
Tenessy

🐛 + + + Enoch Gao
Enoch Gao

📖 🇨🇳 + Francisco Palma
Francisco Palma

🐛 + Tamim Arefin Anik
Tamim Arefin Anik

🐛 + Matheus B.
Matheus B.

🐛 + Stef Heyenrath
Stef Heyenrath

📖 + mathisvester
mathisvester

🐛 @@ -81,6 +103,6 @@ Contributions of any kind are welcome. If I have forgotten to add you as a contributor, please reach out to me. 🙏 -## Licensev +## License MIT diff --git a/apps/angular/projection/.eslintrc.json b/apps/angular/1-projection/.eslintrc.json similarity index 100% rename from apps/angular/projection/.eslintrc.json rename to apps/angular/1-projection/.eslintrc.json diff --git a/apps/angular/projection/README.md b/apps/angular/1-projection/README.md similarity index 100% rename from apps/angular/projection/README.md rename to apps/angular/1-projection/README.md diff --git a/apps/angular/1-projection/jest.config.ts b/apps/angular/1-projection/jest.config.ts new file mode 100644 index 000000000..fe5eb1627 --- /dev/null +++ b/apps/angular/1-projection/jest.config.ts @@ -0,0 +1,23 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-projection', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: {}, + coverageDirectory: '../../../coverage/apps/angular/1-projection', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/1-projection/project.json b/apps/angular/1-projection/project.json new file mode 100644 index 000000000..42ed1604f --- /dev/null +++ b/apps/angular/1-projection/project.json @@ -0,0 +1,85 @@ +{ + "name": "angular-projection", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/1-projection/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/1-projection", + "index": "apps/angular/1-projection/src/index.html", + "main": "apps/angular/1-projection/src/main.ts", + "polyfills": ["apps/angular/1-projection/src/polyfills.ts"], + "tsConfig": "apps/angular/1-projection/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/1-projection/src/favicon.ico", + "apps/angular/1-projection/src/assets" + ], + "styles": ["apps/angular/1-projection/src/styles.scss"], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-projection:build:production" + }, + "development": { + "buildTarget": "angular-projection:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-projection:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/1-projection/src/app/app.component.ts b/apps/angular/1-projection/src/app/app.component.ts new file mode 100644 index 000000000..df654bbc2 --- /dev/null +++ b/apps/angular/1-projection/src/app/app.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +import { CityCardComponent } from './component/city-card/city-card.component'; +import { StudentCardComponent } from './component/student-card/student-card.component'; +import { TeacherCardComponent } from './component/teacher-card/teacher-card.component'; + +@Component({ + selector: 'app-root', + template: ` +
+ + + +
+ `, + imports: [TeacherCardComponent, StudentCardComponent, CityCardComponent], +}) +export class AppComponent {} diff --git a/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts b/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts new file mode 100644 index 000000000..8895c8c84 --- /dev/null +++ b/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts @@ -0,0 +1,9 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-city-card', + template: 'TODO City', + imports: [], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CityCardComponent {} diff --git a/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts b/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts new file mode 100644 index 000000000..bdfa4abd4 --- /dev/null +++ b/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts @@ -0,0 +1,40 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + OnInit, +} from '@angular/core'; +import { FakeHttpService } from '../../data-access/fake-http.service'; +import { StudentStore } from '../../data-access/student.store'; +import { CardType } from '../../model/card.model'; +import { CardComponent } from '../../ui/card/card.component'; + +@Component({ + selector: 'app-student-card', + template: ` + + `, + styles: [ + ` + ::ng-deep .bg-light-green { + background-color: rgba(0, 250, 0, 0.1); + } + `, + ], + imports: [CardComponent], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class StudentCardComponent implements OnInit { + private http = inject(FakeHttpService); + private store = inject(StudentStore); + + students = this.store.students; + cardType = CardType.STUDENT; + + ngOnInit(): void { + this.http.fetchStudents$.subscribe((s) => this.store.addAll(s)); + } +} diff --git a/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts b/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts new file mode 100644 index 000000000..adf0ad3c1 --- /dev/null +++ b/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts @@ -0,0 +1,34 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { FakeHttpService } from '../../data-access/fake-http.service'; +import { TeacherStore } from '../../data-access/teacher.store'; +import { CardType } from '../../model/card.model'; +import { CardComponent } from '../../ui/card/card.component'; + +@Component({ + selector: 'app-teacher-card', + template: ` + + `, + styles: [ + ` + ::ng-deep .bg-light-red { + background-color: rgba(250, 0, 0, 0.1); + } + `, + ], + imports: [CardComponent], +}) +export class TeacherCardComponent implements OnInit { + private http = inject(FakeHttpService); + private store = inject(TeacherStore); + + teachers = this.store.teachers; + cardType = CardType.TEACHER; + + ngOnInit(): void { + this.http.fetchTeachers$.subscribe((t) => this.store.addAll(t)); + } +} diff --git a/apps/angular/1-projection/src/app/data-access/city.store.ts b/apps/angular/1-projection/src/app/data-access/city.store.ts new file mode 100644 index 000000000..a8b523569 --- /dev/null +++ b/apps/angular/1-projection/src/app/data-access/city.store.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; +import { City } from '../model/city.model'; + +@Injectable({ + providedIn: 'root', +}) +export class CityStore { + private cities = signal([]); + + addAll(cities: City[]) { + this.cities.set(cities); + } + + addOne(city: City) { + this.cities.set([...this.cities(), city]); + } + + deleteOne(id: number) { + this.cities.set(this.cities().filter((s) => s.id !== id)); + } +} diff --git a/apps/angular/projection/src/app/data-access/fake-http.service.ts b/apps/angular/1-projection/src/app/data-access/fake-http.service.ts similarity index 100% rename from apps/angular/projection/src/app/data-access/fake-http.service.ts rename to apps/angular/1-projection/src/app/data-access/fake-http.service.ts diff --git a/apps/angular/1-projection/src/app/data-access/student.store.ts b/apps/angular/1-projection/src/app/data-access/student.store.ts new file mode 100644 index 000000000..6e7f57022 --- /dev/null +++ b/apps/angular/1-projection/src/app/data-access/student.store.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; +import { Student } from '../model/student.model'; + +@Injectable({ + providedIn: 'root', +}) +export class StudentStore { + public students = signal([]); + + addAll(students: Student[]) { + this.students.set(students); + } + + addOne(student: Student) { + this.students.set([...this.students(), student]); + } + + deleteOne(id: number) { + this.students.set(this.students().filter((s) => s.id !== id)); + } +} diff --git a/apps/angular/1-projection/src/app/data-access/teacher.store.ts b/apps/angular/1-projection/src/app/data-access/teacher.store.ts new file mode 100644 index 000000000..5f6dae989 --- /dev/null +++ b/apps/angular/1-projection/src/app/data-access/teacher.store.ts @@ -0,0 +1,21 @@ +import { Injectable, signal } from '@angular/core'; +import { Teacher } from '../model/teacher.model'; + +@Injectable({ + providedIn: 'root', +}) +export class TeacherStore { + public teachers = signal([]); + + addAll(teachers: Teacher[]) { + this.teachers.set(teachers); + } + + addOne(teacher: Teacher) { + this.teachers.set([...this.teachers(), teacher]); + } + + deleteOne(id: number) { + this.teachers.set(this.teachers().filter((t) => t.id !== id)); + } +} diff --git a/apps/angular/projection/src/app/model/card.model.ts b/apps/angular/1-projection/src/app/model/card.model.ts similarity index 100% rename from apps/angular/projection/src/app/model/card.model.ts rename to apps/angular/1-projection/src/app/model/card.model.ts diff --git a/apps/angular/projection/src/app/model/city.model.ts b/apps/angular/1-projection/src/app/model/city.model.ts similarity index 100% rename from apps/angular/projection/src/app/model/city.model.ts rename to apps/angular/1-projection/src/app/model/city.model.ts diff --git a/apps/angular/projection/src/app/model/student.model.ts b/apps/angular/1-projection/src/app/model/student.model.ts similarity index 100% rename from apps/angular/projection/src/app/model/student.model.ts rename to apps/angular/1-projection/src/app/model/student.model.ts diff --git a/apps/angular/projection/src/app/model/teacher.model.ts b/apps/angular/1-projection/src/app/model/teacher.model.ts similarity index 100% rename from apps/angular/projection/src/app/model/teacher.model.ts rename to apps/angular/1-projection/src/app/model/teacher.model.ts diff --git a/apps/angular/1-projection/src/app/ui/card/card.component.ts b/apps/angular/1-projection/src/app/ui/card/card.component.ts new file mode 100644 index 000000000..1a6c3648c --- /dev/null +++ b/apps/angular/1-projection/src/app/ui/card/card.component.ts @@ -0,0 +1,58 @@ +import { NgOptimizedImage } from '@angular/common'; +import { Component, inject, input } from '@angular/core'; +import { randStudent, randTeacher } from '../../data-access/fake-http.service'; +import { StudentStore } from '../../data-access/student.store'; +import { TeacherStore } from '../../data-access/teacher.store'; +import { CardType } from '../../model/card.model'; +import { ListItemComponent } from '../list-item/list-item.component'; + +@Component({ + selector: 'app-card', + template: ` +
+ @if (type() === CardType.TEACHER) { + + } + @if (type() === CardType.STUDENT) { + + } + +
+ @for (item of list(); track item) { + + } +
+ + +
+ `, + imports: [ListItemComponent, NgOptimizedImage], +}) +export class CardComponent { + private teacherStore = inject(TeacherStore); + private studentStore = inject(StudentStore); + + readonly list = input(null); + readonly type = input.required(); + readonly customClass = input(''); + + CardType = CardType; + + addNewItem() { + const type = this.type(); + if (type === CardType.TEACHER) { + this.teacherStore.addOne(randTeacher()); + } else if (type === CardType.STUDENT) { + this.studentStore.addOne(randStudent()); + } + } +} diff --git a/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts b/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts new file mode 100644 index 000000000..5d504f372 --- /dev/null +++ b/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts @@ -0,0 +1,39 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + input, +} from '@angular/core'; +import { StudentStore } from '../../data-access/student.store'; +import { TeacherStore } from '../../data-access/teacher.store'; +import { CardType } from '../../model/card.model'; + +@Component({ + selector: 'app-list-item', + template: ` +
+ {{ name() }} + +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ListItemComponent { + private teacherStore = inject(TeacherStore); + private studentStore = inject(StudentStore); + + readonly id = input.required(); + readonly name = input.required(); + readonly type = input.required(); + + delete(id: number) { + const type = this.type(); + if (type === CardType.TEACHER) { + this.teacherStore.deleteOne(id); + } else if (type === CardType.STUDENT) { + this.studentStore.deleteOne(id); + } + } +} diff --git a/apps/angular/anchor-scrolling/src/assets/.gitkeep b/apps/angular/1-projection/src/assets/.gitkeep similarity index 100% rename from apps/angular/anchor-scrolling/src/assets/.gitkeep rename to apps/angular/1-projection/src/assets/.gitkeep diff --git a/apps/angular/projection/src/assets/img/city.png b/apps/angular/1-projection/src/assets/img/city.png similarity index 100% rename from apps/angular/projection/src/assets/img/city.png rename to apps/angular/1-projection/src/assets/img/city.png diff --git a/apps/angular/projection/src/assets/img/student.webp b/apps/angular/1-projection/src/assets/img/student.webp similarity index 100% rename from apps/angular/projection/src/assets/img/student.webp rename to apps/angular/1-projection/src/assets/img/student.webp diff --git a/apps/angular/projection/src/assets/img/teacher.png b/apps/angular/1-projection/src/assets/img/teacher.png similarity index 100% rename from apps/angular/projection/src/assets/img/teacher.png rename to apps/angular/1-projection/src/assets/img/teacher.png diff --git a/apps/angular/projection/src/assets/svg/trash.svg b/apps/angular/1-projection/src/assets/svg/trash.svg similarity index 100% rename from apps/angular/projection/src/assets/svg/trash.svg rename to apps/angular/1-projection/src/assets/svg/trash.svg diff --git a/apps/angular/anchor-scrolling/src/favicon.ico b/apps/angular/1-projection/src/favicon.ico similarity index 100% rename from apps/angular/anchor-scrolling/src/favicon.ico rename to apps/angular/1-projection/src/favicon.ico diff --git a/apps/angular/1-projection/src/index.html b/apps/angular/1-projection/src/index.html new file mode 100644 index 000000000..bb9c8bc84 --- /dev/null +++ b/apps/angular/1-projection/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-projection + + + + + + + + diff --git a/apps/angular/1-projection/src/main.ts b/apps/angular/1-projection/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/1-projection/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/context-outlet-type/src/polyfills.ts b/apps/angular/1-projection/src/polyfills.ts similarity index 100% rename from apps/angular/context-outlet-type/src/polyfills.ts rename to apps/angular/1-projection/src/polyfills.ts diff --git a/apps/angular/projection/src/styles.scss b/apps/angular/1-projection/src/styles.scss similarity index 100% rename from apps/angular/projection/src/styles.scss rename to apps/angular/1-projection/src/styles.scss diff --git a/apps/angular/1-projection/src/test-setup.ts b/apps/angular/1-projection/src/test-setup.ts new file mode 100644 index 000000000..58c511e08 --- /dev/null +++ b/apps/angular/1-projection/src/test-setup.ts @@ -0,0 +1,3 @@ +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/anchor-scrolling/tailwind.config.js b/apps/angular/1-projection/tailwind.config.js similarity index 100% rename from apps/angular/anchor-scrolling/tailwind.config.js rename to apps/angular/1-projection/tailwind.config.js diff --git a/apps/angular/1-projection/tsconfig.app.json b/apps/angular/1-projection/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/1-projection/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/projection/tsconfig.editor.json b/apps/angular/1-projection/tsconfig.editor.json similarity index 100% rename from apps/angular/projection/tsconfig.editor.json rename to apps/angular/1-projection/tsconfig.editor.json diff --git a/apps/angular/1-projection/tsconfig.json b/apps/angular/1-projection/tsconfig.json new file mode 100644 index 000000000..2e21bd713 --- /dev/null +++ b/apps/angular/1-projection/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/1-projection/tsconfig.spec.json b/apps/angular/1-projection/tsconfig.spec.json new file mode 100644 index 000000000..a26655f5a --- /dev/null +++ b/apps/angular/1-projection/tsconfig.spec.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/apps/angular/crud/.eslintrc.json b/apps/angular/10-utility-wrapper-pipe/.eslintrc.json similarity index 100% rename from apps/angular/crud/.eslintrc.json rename to apps/angular/10-utility-wrapper-pipe/.eslintrc.json diff --git a/apps/angular/10-utility-wrapper-pipe/README.md b/apps/angular/10-utility-wrapper-pipe/README.md new file mode 100644 index 000000000..aac426271 --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/README.md @@ -0,0 +1,13 @@ +# Utility Wrapper Pipe + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-utility-wrapper-pipe +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/10-pipe-utility/). diff --git a/apps/angular/10-utility-wrapper-pipe/project.json b/apps/angular/10-utility-wrapper-pipe/project.json new file mode 100644 index 000000000..37a204043 --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-utility-wrapper-pipe", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/10-utility-wrapper-pipe/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/10-utility-wrapper-pipe", + "index": "apps/angular/10-utility-wrapper-pipe/src/index.html", + "main": "apps/angular/10-utility-wrapper-pipe/src/main.ts", + "polyfills": "apps/angular/10-utility-wrapper-pipe/src/polyfills.ts", + "tsConfig": "apps/angular/10-utility-wrapper-pipe/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/10-utility-wrapper-pipe/src/favicon.ico", + "apps/angular/10-utility-wrapper-pipe/src/assets" + ], + "styles": ["apps/angular/10-utility-wrapper-pipe/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-utility-wrapper-pipe:build:production" + }, + "development": { + "buildTarget": "angular-utility-wrapper-pipe:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-utility-wrapper-pipe:build" + } + } + } +} diff --git a/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts b/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts new file mode 100644 index 000000000..9a8156a5f --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { PersonUtils } from './person.utils'; + +@Component({ + selector: 'app-root', + template: ` + @for (activity of activities; track activity.name) { + {{ activity.name }} : + @for ( + person of persons; + track person.name; + let index = $index; + let isFirst = $first + ) { + {{ showName(person.name, index) }} + {{ isAllowed(person.age, isFirst, activity.minimumAge) }} + } + } + `, +}) +export class AppComponent { + persons = [ + { name: 'Toto', age: 10 }, + { name: 'Jack', age: 15 }, + { name: 'John', age: 30 }, + ]; + + activities = [ + { name: 'biking', minimumAge: 12 }, + { name: 'hiking', minimumAge: 25 }, + { name: 'dancing', minimumAge: 1 }, + ]; + + showName = PersonUtils.showName; + + isAllowed = PersonUtils.isAllowed; +} diff --git a/apps/angular/pipe-hard/src/app/person.utils.ts b/apps/angular/10-utility-wrapper-pipe/src/app/person.utils.ts similarity index 100% rename from apps/angular/pipe-hard/src/app/person.utils.ts rename to apps/angular/10-utility-wrapper-pipe/src/app/person.utils.ts diff --git a/apps/angular/bug-cd/src/assets/.gitkeep b/apps/angular/10-utility-wrapper-pipe/src/assets/.gitkeep similarity index 100% rename from apps/angular/bug-cd/src/assets/.gitkeep rename to apps/angular/10-utility-wrapper-pipe/src/assets/.gitkeep diff --git a/apps/angular/bug-cd/src/favicon.ico b/apps/angular/10-utility-wrapper-pipe/src/favicon.ico similarity index 100% rename from apps/angular/bug-cd/src/favicon.ico rename to apps/angular/10-utility-wrapper-pipe/src/favicon.ico diff --git a/apps/angular/10-utility-wrapper-pipe/src/index.html b/apps/angular/10-utility-wrapper-pipe/src/index.html new file mode 100644 index 000000000..01d31a163 --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-utility-wrapper-pipe + + + + + + + + diff --git a/apps/angular/10-utility-wrapper-pipe/src/main.ts b/apps/angular/10-utility-wrapper-pipe/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/crud/src/polyfills.ts b/apps/angular/10-utility-wrapper-pipe/src/polyfills.ts similarity index 100% rename from apps/angular/crud/src/polyfills.ts rename to apps/angular/10-utility-wrapper-pipe/src/polyfills.ts diff --git a/apps/angular/context-outlet-type/src/styles.scss b/apps/angular/10-utility-wrapper-pipe/src/styles.scss similarity index 100% rename from apps/angular/context-outlet-type/src/styles.scss rename to apps/angular/10-utility-wrapper-pipe/src/styles.scss diff --git a/apps/angular/10-utility-wrapper-pipe/tsconfig.app.json b/apps/angular/10-utility-wrapper-pipe/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/context-outlet-type/tsconfig.editor.json b/apps/angular/10-utility-wrapper-pipe/tsconfig.editor.json similarity index 100% rename from apps/angular/context-outlet-type/tsconfig.editor.json rename to apps/angular/10-utility-wrapper-pipe/tsconfig.editor.json diff --git a/apps/angular/10-utility-wrapper-pipe/tsconfig.json b/apps/angular/10-utility-wrapper-pipe/tsconfig.json new file mode 100644 index 000000000..f512037ca --- /dev/null +++ b/apps/angular/10-utility-wrapper-pipe/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/anchor-scrolling/.eslintrc.json b/apps/angular/13-highly-customizable-css/.eslintrc.json similarity index 100% rename from apps/angular/anchor-scrolling/.eslintrc.json rename to apps/angular/13-highly-customizable-css/.eslintrc.json diff --git a/apps/angular/13-highly-customizable-css/README.md b/apps/angular/13-highly-customizable-css/README.md new file mode 100644 index 000000000..d63171ae6 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/README.md @@ -0,0 +1,13 @@ +# Highly Customizable CSS + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-highly-customizable-css +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/13-styling/). diff --git a/apps/angular/13-highly-customizable-css/project.json b/apps/angular/13-highly-customizable-css/project.json new file mode 100644 index 000000000..c20d3bb48 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-highly-customizable-css", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/13-highly-customizable-css/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/13-highly-customizable-css", + "index": "apps/angular/13-highly-customizable-css/src/index.html", + "main": "apps/angular/13-highly-customizable-css/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/13-highly-customizable-css/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/13-highly-customizable-css/src/favicon.ico", + "apps/angular/13-highly-customizable-css/src/assets" + ], + "styles": ["apps/angular/13-highly-customizable-css/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-highly-customizable-css:build:production" + }, + "development": { + "buildTarget": "angular-highly-customizable-css:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-highly-customizable-css:build" + } + } + } +} diff --git a/apps/angular/13-highly-customizable-css/src/app/page.component.ts b/apps/angular/13-highly-customizable-css/src/app/page.component.ts new file mode 100644 index 000000000..029ca52d2 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/src/app/page.component.ts @@ -0,0 +1,16 @@ +/* eslint-disable @angular-eslint/component-selector */ +import { Component } from '@angular/core'; +import { TextStaticComponent } from './static-text.component'; +import { TextComponent } from './text.component'; + +@Component({ + selector: 'page', + imports: [TextStaticComponent, TextComponent], + template: ` + + + + This is a blue text + `, +}) +export class PageComponent {} diff --git a/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts b/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts new file mode 100644 index 000000000..703e2a538 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts @@ -0,0 +1,38 @@ +/* eslint-disable @angular-eslint/component-selector */ +import { Component, computed, input } from '@angular/core'; +import { TextComponent } from './text.component'; + +export type StaticTextType = 'normal' | 'warning' | 'error'; + +@Component({ + selector: 'static-text', + imports: [TextComponent], + template: ` + This is a static text + `, +}) +export class TextStaticComponent { + type = input('normal'); + + font = computed(() => { + switch (this.type()) { + case 'error': + return 30; + case 'warning': + return 25; + default: + return 10; + } + }); + + color = computed(() => { + switch (this.type()) { + case 'error': + return 'red'; + case 'warning': + return 'orange'; + default: + return 'black'; + } + }); +} diff --git a/apps/angular/13-highly-customizable-css/src/app/text.component.ts b/apps/angular/13-highly-customizable-css/src/app/text.component.ts new file mode 100644 index 000000000..07e3e6255 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/src/app/text.component.ts @@ -0,0 +1,15 @@ +/* eslint-disable @angular-eslint/component-selector */ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'text', + template: ` +

+ +

+ `, +}) +export class TextComponent { + font = input(10); + color = input('black'); +} diff --git a/apps/angular/crud/src/assets/.gitkeep b/apps/angular/13-highly-customizable-css/src/assets/.gitkeep similarity index 100% rename from apps/angular/crud/src/assets/.gitkeep rename to apps/angular/13-highly-customizable-css/src/assets/.gitkeep diff --git a/apps/angular/context-outlet-type/src/favicon.ico b/apps/angular/13-highly-customizable-css/src/favicon.ico similarity index 100% rename from apps/angular/context-outlet-type/src/favicon.ico rename to apps/angular/13-highly-customizable-css/src/favicon.ico diff --git a/apps/angular/13-highly-customizable-css/src/index.html b/apps/angular/13-highly-customizable-css/src/index.html new file mode 100644 index 000000000..e4a84b456 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-highly-customizable-css + + + + + + + + diff --git a/apps/angular/13-highly-customizable-css/src/main.ts b/apps/angular/13-highly-customizable-css/src/main.ts new file mode 100644 index 000000000..4afd673b4 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { PageComponent } from './app/page.component'; + +bootstrapApplication(PageComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/ngfor-enhancement/src/styles.scss b/apps/angular/13-highly-customizable-css/src/styles.scss similarity index 100% rename from apps/angular/ngfor-enhancement/src/styles.scss rename to apps/angular/13-highly-customizable-css/src/styles.scss diff --git a/apps/angular/13-highly-customizable-css/tsconfig.app.json b/apps/angular/13-highly-customizable-css/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/di/tsconfig.editor.json b/apps/angular/13-highly-customizable-css/tsconfig.editor.json similarity index 100% rename from apps/angular/di/tsconfig.editor.json rename to apps/angular/13-highly-customizable-css/tsconfig.editor.json diff --git a/apps/angular/13-highly-customizable-css/tsconfig.json b/apps/angular/13-highly-customizable-css/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/angular/13-highly-customizable-css/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/di/.eslintrc.json b/apps/angular/16-master-dependency-injection/.eslintrc.json similarity index 100% rename from apps/angular/di/.eslintrc.json rename to apps/angular/16-master-dependency-injection/.eslintrc.json diff --git a/apps/angular/16-master-dependency-injection/README.md b/apps/angular/16-master-dependency-injection/README.md new file mode 100644 index 000000000..be19c1ba3 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/README.md @@ -0,0 +1,13 @@ +# Master Dependancy Injection + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-master-dependency-injection +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/16-di/). diff --git a/apps/angular/16-master-dependency-injection/project.json b/apps/angular/16-master-dependency-injection/project.json new file mode 100644 index 000000000..4eb6bd95e --- /dev/null +++ b/apps/angular/16-master-dependency-injection/project.json @@ -0,0 +1,75 @@ +{ + "name": "angular-master-dependency-injection", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/16-master-dependency-injection/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/16-master-dependency-injection", + "index": "apps/angular/16-master-dependency-injection/src/index.html", + "main": "apps/angular/16-master-dependency-injection/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/16-master-dependency-injection/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/16-master-dependency-injection/src/favicon.ico", + "apps/angular/16-master-dependency-injection/src/assets" + ], + "styles": [ + "apps/angular/16-master-dependency-injection/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-master-dependency-injection:build:production" + }, + "development": { + "buildTarget": "angular-master-dependency-injection:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-master-dependency-injection:build" + } + } + } +} diff --git a/apps/angular/16-master-dependency-injection/src/app/app.component.ts b/apps/angular/16-master-dependency-injection/src/app/app.component.ts new file mode 100644 index 000000000..332ec9877 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/src/app/app.component.ts @@ -0,0 +1,54 @@ +import { TableComponent } from '@angular-challenges/shared/ui'; +import { AsyncPipe } from '@angular/common'; +import { ChangeDetectionStrategy, Component, Directive } from '@angular/core'; +import { CurrencyPipe } from './currency.pipe'; +import { CurrencyService } from './currency.service'; +import { Product, products } from './product.model'; + +interface ProductContext { + $implicit: Product; +} + +@Directive({ + selector: 'ng-template[product]', +}) +export class ProductDirective { + static ngTemplateContextGuard( + dir: ProductDirective, + ctx: unknown, + ): ctx is ProductContext { + return true; + } +} + +@Component({ + imports: [TableComponent, CurrencyPipe, AsyncPipe, ProductDirective], + providers: [CurrencyService], + selector: 'app-root', + template: ` + + + + @for (col of displayedColumns; track $index) { + + } + + + + + + + + + + +
+ {{ col }} +
{{ product.name }}{{ product.priceA | currency | async }}{{ product.priceB | currency | async }}{{ product.priceC | currency | async }}
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + products = products; + displayedColumns = ['name', 'priceA', 'priceB', 'priceC']; +} diff --git a/apps/angular/16-master-dependency-injection/src/app/currency.pipe.ts b/apps/angular/16-master-dependency-injection/src/app/currency.pipe.ts new file mode 100644 index 000000000..efa408eb8 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/src/app/currency.pipe.ts @@ -0,0 +1,16 @@ +import { inject, Pipe, PipeTransform } from '@angular/core'; +import { map } from 'rxjs'; +import { CurrencyService } from './currency.service'; + +@Pipe({ + name: 'currency', +}) +export class CurrencyPipe implements PipeTransform { + currencyService = inject(CurrencyService); + + transform(price: number) { + return this.currencyService.symbol$.pipe( + map((s) => `${String(price)}${s}`), + ); + } +} diff --git a/apps/angular/di/src/app/currency.service.ts b/apps/angular/16-master-dependency-injection/src/app/currency.service.ts similarity index 100% rename from apps/angular/di/src/app/currency.service.ts rename to apps/angular/16-master-dependency-injection/src/app/currency.service.ts diff --git a/apps/angular/di/src/app/product.model.ts b/apps/angular/16-master-dependency-injection/src/app/product.model.ts similarity index 100% rename from apps/angular/di/src/app/product.model.ts rename to apps/angular/16-master-dependency-injection/src/app/product.model.ts diff --git a/apps/angular/decoupling/src/assets/.gitkeep b/apps/angular/16-master-dependency-injection/src/assets/.gitkeep similarity index 100% rename from apps/angular/decoupling/src/assets/.gitkeep rename to apps/angular/16-master-dependency-injection/src/assets/.gitkeep diff --git a/apps/angular/crud/src/favicon.ico b/apps/angular/16-master-dependency-injection/src/favicon.ico similarity index 100% rename from apps/angular/crud/src/favicon.ico rename to apps/angular/16-master-dependency-injection/src/favicon.ico diff --git a/apps/angular/16-master-dependency-injection/src/index.html b/apps/angular/16-master-dependency-injection/src/index.html new file mode 100644 index 000000000..be35bf8c8 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-master-dependancy-injection + + + + + + + + diff --git a/apps/angular/16-master-dependency-injection/src/main.ts b/apps/angular/16-master-dependency-injection/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/16-master-dependency-injection/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/di/src/styles.scss b/apps/angular/16-master-dependency-injection/src/styles.scss similarity index 100% rename from apps/angular/di/src/styles.scss rename to apps/angular/16-master-dependency-injection/src/styles.scss diff --git a/apps/angular/16-master-dependency-injection/tsconfig.app.json b/apps/angular/16-master-dependency-injection/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/router-input/tsconfig.editor.json b/apps/angular/16-master-dependency-injection/tsconfig.editor.json similarity index 100% rename from apps/angular/router-input/tsconfig.editor.json rename to apps/angular/16-master-dependency-injection/tsconfig.editor.json diff --git a/apps/angular/16-master-dependency-injection/tsconfig.json b/apps/angular/16-master-dependency-injection/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/angular/16-master-dependency-injection/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/bug-cd/.eslintrc.json b/apps/angular/21-anchor-navigation/.eslintrc.json similarity index 100% rename from apps/angular/bug-cd/.eslintrc.json rename to apps/angular/21-anchor-navigation/.eslintrc.json diff --git a/apps/angular/21-anchor-navigation/README.md b/apps/angular/21-anchor-navigation/README.md new file mode 100644 index 000000000..3683899ba --- /dev/null +++ b/apps/angular/21-anchor-navigation/README.md @@ -0,0 +1,13 @@ +# Anchor Navigation + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-anchor-navigation +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/21-achor-scrolling/). diff --git a/apps/angular/21-anchor-navigation/jest.config.ts b/apps/angular/21-anchor-navigation/jest.config.ts new file mode 100644 index 000000000..496a9fe76 --- /dev/null +++ b/apps/angular/21-anchor-navigation/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'anchor-navigation-anchor-navigation', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/21-anchor-navigation', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/21-anchor-navigation/project.json b/apps/angular/21-anchor-navigation/project.json new file mode 100644 index 000000000..782bb1ec4 --- /dev/null +++ b/apps/angular/21-anchor-navigation/project.json @@ -0,0 +1,84 @@ +{ + "name": "angular-anchor-navigation", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/21-anchor-navigation/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/21-anchor-navigation", + "index": "apps/angular/21-anchor-navigation/src/index.html", + "main": "apps/angular/21-anchor-navigation/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/21-anchor-navigation/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/21-anchor-navigation/src/favicon.ico", + "apps/angular/21-anchor-navigation/src/assets" + ], + "styles": ["apps/angular/21-anchor-navigation/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-anchor-navigation:build:production" + }, + "development": { + "buildTarget": "angular-anchor-navigation:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-anchor-navigation:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/21-anchor-navigation/src/app/app.component.ts b/apps/angular/21-anchor-navigation/src/app/app.component.ts new file mode 100644 index 000000000..5caca0271 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent {} diff --git a/apps/angular/anchor-scrolling/src/app/app.config.ts b/apps/angular/21-anchor-navigation/src/app/app.config.ts similarity index 100% rename from apps/angular/anchor-scrolling/src/app/app.config.ts rename to apps/angular/21-anchor-navigation/src/app/app.config.ts diff --git a/apps/angular/anchor-scrolling/src/app/app.routes.ts b/apps/angular/21-anchor-navigation/src/app/app.routes.ts similarity index 100% rename from apps/angular/anchor-scrolling/src/app/app.routes.ts rename to apps/angular/21-anchor-navigation/src/app/app.routes.ts diff --git a/apps/angular/21-anchor-navigation/src/app/foo.component.ts b/apps/angular/21-anchor-navigation/src/app/foo.component.ts new file mode 100644 index 000000000..6744c3662 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/app/foo.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { NavButtonComponent } from './nav-button.component'; + +@Component({ + imports: [NavButtonComponent], + selector: 'app-foo', + template: ` + Welcome to foo page + Home Page +
section 1
+
section 2
+ `, +}) +export class FooComponent {} diff --git a/apps/angular/21-anchor-navigation/src/app/home.component.ts b/apps/angular/21-anchor-navigation/src/app/home.component.ts new file mode 100644 index 000000000..6ef9bc2b6 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/app/home.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { NavButtonComponent } from './nav-button.component'; + +@Component({ + imports: [NavButtonComponent], + selector: 'app-home', + template: ` + Foo Page +
+ Empty + Scroll Bottom +
+
+ I want to scroll each + Scroll Top +
+ `, +}) +export class HomeComponent {} diff --git a/apps/angular/21-anchor-navigation/src/app/nav-button.component.ts b/apps/angular/21-anchor-navigation/src/app/nav-button.component.ts new file mode 100644 index 000000000..7a22c7f38 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/app/nav-button.component.ts @@ -0,0 +1,17 @@ +/* eslint-disable @angular-eslint/component-selector */ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'nav-button', + template: ` + + + + `, + host: { + class: 'block w-fit border border-red-500 rounded-md p-4 m-2', + }, +}) +export class NavButtonComponent { + href = input(''); +} diff --git a/apps/angular/di/src/assets/.gitkeep b/apps/angular/21-anchor-navigation/src/assets/.gitkeep similarity index 100% rename from apps/angular/di/src/assets/.gitkeep rename to apps/angular/21-anchor-navigation/src/assets/.gitkeep diff --git a/apps/angular/decoupling/src/favicon.ico b/apps/angular/21-anchor-navigation/src/favicon.ico similarity index 100% rename from apps/angular/decoupling/src/favicon.ico rename to apps/angular/21-anchor-navigation/src/favicon.ico diff --git a/apps/angular/21-anchor-navigation/src/index.html b/apps/angular/21-anchor-navigation/src/index.html new file mode 100644 index 000000000..06a706a0a --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-anchor-navigation + + + + + + + + diff --git a/apps/angular/21-anchor-navigation/src/main.ts b/apps/angular/21-anchor-navigation/src/main.ts new file mode 100644 index 000000000..4fcb1ec76 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; + +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/anchor-scrolling/src/styles.scss b/apps/angular/21-anchor-navigation/src/styles.scss similarity index 100% rename from apps/angular/anchor-scrolling/src/styles.scss rename to apps/angular/21-anchor-navigation/src/styles.scss diff --git a/apps/angular/21-anchor-navigation/src/test-setup.ts b/apps/angular/21-anchor-navigation/src/test-setup.ts new file mode 100644 index 000000000..58c511e08 --- /dev/null +++ b/apps/angular/21-anchor-navigation/src/test-setup.ts @@ -0,0 +1,3 @@ +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/bug-cd/tailwind.config.js b/apps/angular/21-anchor-navigation/tailwind.config.js similarity index 100% rename from apps/angular/bug-cd/tailwind.config.js rename to apps/angular/21-anchor-navigation/tailwind.config.js diff --git a/apps/angular/21-anchor-navigation/tsconfig.app.json b/apps/angular/21-anchor-navigation/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/21-anchor-navigation/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/anchor-scrolling/tsconfig.editor.json b/apps/angular/21-anchor-navigation/tsconfig.editor.json similarity index 100% rename from apps/angular/anchor-scrolling/tsconfig.editor.json rename to apps/angular/21-anchor-navigation/tsconfig.editor.json diff --git a/apps/angular/21-anchor-navigation/tsconfig.json b/apps/angular/21-anchor-navigation/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/angular/21-anchor-navigation/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/21-anchor-navigation/tsconfig.spec.json b/apps/angular/21-anchor-navigation/tsconfig.spec.json new file mode 100644 index 000000000..032d49d7a --- /dev/null +++ b/apps/angular/21-anchor-navigation/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/decoupling/.eslintrc.json b/apps/angular/22-router-input/.eslintrc.json similarity index 100% rename from apps/angular/decoupling/.eslintrc.json rename to apps/angular/22-router-input/.eslintrc.json diff --git a/apps/angular/router-input/README.md b/apps/angular/22-router-input/README.md similarity index 100% rename from apps/angular/router-input/README.md rename to apps/angular/22-router-input/README.md diff --git a/apps/angular/22-router-input/project.json b/apps/angular/22-router-input/project.json new file mode 100644 index 000000000..d0cd43a08 --- /dev/null +++ b/apps/angular/22-router-input/project.json @@ -0,0 +1,72 @@ +{ + "name": "angular-router-input", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/22-router-input/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/22-router-input", + "index": "apps/angular/22-router-input/src/index.html", + "main": "apps/angular/22-router-input/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/22-router-input/tsconfig.app.json", + "assets": [ + "apps/angular/22-router-input/src/favicon.ico", + "apps/angular/22-router-input/src/assets" + ], + "styles": ["apps/angular/22-router-input/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-router-input:build:production" + }, + "development": { + "buildTarget": "angular-router-input:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-router-input:build" + } + } + } +} diff --git a/apps/angular/22-router-input/src/app/app.component.ts b/apps/angular/22-router-input/src/app/app.component.ts new file mode 100644 index 000000000..9dfc11200 --- /dev/null +++ b/apps/angular/22-router-input/src/app/app.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { RouterLink, RouterModule } from '@angular/router'; + +@Component({ + imports: [RouterLink, RouterModule, ReactiveFormsModule], + selector: 'app-root', + template: ` + + + + + + + + `, +}) +export class AppComponent { + userName = new FormControl(); + testId = new FormControl(); +} diff --git a/apps/angular/router-input/src/app/app.config.ts b/apps/angular/22-router-input/src/app/app.config.ts similarity index 100% rename from apps/angular/router-input/src/app/app.config.ts rename to apps/angular/22-router-input/src/app/app.config.ts diff --git a/apps/angular/router-input/src/app/app.routes.ts b/apps/angular/22-router-input/src/app/app.routes.ts similarity index 100% rename from apps/angular/router-input/src/app/app.routes.ts rename to apps/angular/22-router-input/src/app/app.routes.ts diff --git a/apps/angular/22-router-input/src/app/home.component.ts b/apps/angular/22-router-input/src/app/home.component.ts new file mode 100644 index 000000000..0ddc1501d --- /dev/null +++ b/apps/angular/22-router-input/src/app/home.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +@Component({ + selector: 'app-home', + imports: [], + template: ` +
Home
+ `, +}) +export default class HomeComponent {} diff --git a/apps/angular/router-input/src/app/test.component.ts b/apps/angular/22-router-input/src/app/test.component.ts similarity index 97% rename from apps/angular/router-input/src/app/test.component.ts rename to apps/angular/22-router-input/src/app/test.component.ts index 88c1465f3..747ab4483 100644 --- a/apps/angular/router-input/src/app/test.component.ts +++ b/apps/angular/22-router-input/src/app/test.component.ts @@ -5,7 +5,6 @@ import { map } from 'rxjs'; @Component({ selector: 'app-subscription', - standalone: true, imports: [AsyncPipe], template: `
TestId: {{ testId$ | async }}
diff --git a/apps/angular/injection-token/src/assets/.gitkeep b/apps/angular/22-router-input/src/assets/.gitkeep similarity index 100% rename from apps/angular/injection-token/src/assets/.gitkeep rename to apps/angular/22-router-input/src/assets/.gitkeep diff --git a/apps/angular/di/src/favicon.ico b/apps/angular/22-router-input/src/favicon.ico similarity index 100% rename from apps/angular/di/src/favicon.ico rename to apps/angular/22-router-input/src/favicon.ico diff --git a/apps/angular/22-router-input/src/index.html b/apps/angular/22-router-input/src/index.html new file mode 100644 index 000000000..30e74f7b4 --- /dev/null +++ b/apps/angular/22-router-input/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-router-input + + + + + + + + diff --git a/apps/angular/22-router-input/src/main.ts b/apps/angular/22-router-input/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/22-router-input/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-easy/src/styles.scss b/apps/angular/22-router-input/src/styles.scss similarity index 100% rename from apps/angular/pipe-easy/src/styles.scss rename to apps/angular/22-router-input/src/styles.scss diff --git a/apps/angular/22-router-input/tsconfig.app.json b/apps/angular/22-router-input/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/22-router-input/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/signal-input/tsconfig.editor.json b/apps/angular/22-router-input/tsconfig.editor.json similarity index 100% rename from apps/angular/signal-input/tsconfig.editor.json rename to apps/angular/22-router-input/tsconfig.editor.json diff --git a/apps/angular/22-router-input/tsconfig.json b/apps/angular/22-router-input/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/angular/22-router-input/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/interop-rxjs-signal/.eslintrc.json b/apps/angular/31-module-to-standalone/.eslintrc.json similarity index 100% rename from apps/angular/interop-rxjs-signal/.eslintrc.json rename to apps/angular/31-module-to-standalone/.eslintrc.json diff --git a/apps/angular/module-to-standalone/README.md b/apps/angular/31-module-to-standalone/README.md similarity index 100% rename from apps/angular/module-to-standalone/README.md rename to apps/angular/31-module-to-standalone/README.md diff --git a/apps/angular/31-module-to-standalone/project.json b/apps/angular/31-module-to-standalone/project.json new file mode 100644 index 000000000..b02e0a0a8 --- /dev/null +++ b/apps/angular/31-module-to-standalone/project.json @@ -0,0 +1,72 @@ +{ + "name": "angular-module-to-standalone", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/31-module-to-standalone/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/31-module-to-standalone", + "index": "apps/angular/31-module-to-standalone/src/index.html", + "main": "apps/angular/31-module-to-standalone/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/31-module-to-standalone/tsconfig.app.json", + "assets": [ + "apps/angular/31-module-to-standalone/src/favicon.ico", + "apps/angular/31-module-to-standalone/src/assets" + ], + "styles": ["apps/angular/31-module-to-standalone/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-module-to-standalone:build:production" + }, + "development": { + "buildTarget": "angular-module-to-standalone:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-module-to-standalone:build" + } + } + } +} diff --git a/apps/angular/31-module-to-standalone/src/app/app.component.ts b/apps/angular/31-module-to-standalone/src/app/app.component.ts new file mode 100644 index 000000000..986df84b5 --- /dev/null +++ b/apps/angular/31-module-to-standalone/src/app/app.component.ts @@ -0,0 +1,30 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` +
+ + + +
+ + `, + host: { + class: 'flex flex-col p-4 gap-3', + }, + standalone: false, +}) +export class AppComponent {} diff --git a/apps/angular/module-to-standalone/src/app/app.module.ts b/apps/angular/31-module-to-standalone/src/app/app.module.ts similarity index 100% rename from apps/angular/module-to-standalone/src/app/app.module.ts rename to apps/angular/31-module-to-standalone/src/app/app.module.ts diff --git a/apps/angular/interop-rxjs-signal/src/assets/.gitkeep b/apps/angular/31-module-to-standalone/src/assets/.gitkeep similarity index 100% rename from apps/angular/interop-rxjs-signal/src/assets/.gitkeep rename to apps/angular/31-module-to-standalone/src/assets/.gitkeep diff --git a/apps/angular/injection-token/src/favicon.ico b/apps/angular/31-module-to-standalone/src/favicon.ico similarity index 100% rename from apps/angular/injection-token/src/favicon.ico rename to apps/angular/31-module-to-standalone/src/favicon.ico diff --git a/apps/angular/31-module-to-standalone/src/index.html b/apps/angular/31-module-to-standalone/src/index.html new file mode 100644 index 000000000..fe0d5b978 --- /dev/null +++ b/apps/angular/31-module-to-standalone/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-module-to-standalone + + + + + + + + diff --git a/apps/angular/31-module-to-standalone/src/main.ts b/apps/angular/31-module-to-standalone/src/main.ts new file mode 100644 index 000000000..8cd87d53b --- /dev/null +++ b/apps/angular/31-module-to-standalone/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic() + .bootstrapModule(AppModule, { + applicationProviders: [provideZoneChangeDetection()], + }) + .catch((err) => console.error(err)); diff --git a/apps/angular/bug-cd/src/styles.scss b/apps/angular/31-module-to-standalone/src/styles.scss similarity index 100% rename from apps/angular/bug-cd/src/styles.scss rename to apps/angular/31-module-to-standalone/src/styles.scss diff --git a/apps/angular/module-to-standalone/tailwind.config.js b/apps/angular/31-module-to-standalone/tailwind.config.js similarity index 100% rename from apps/angular/module-to-standalone/tailwind.config.js rename to apps/angular/31-module-to-standalone/tailwind.config.js diff --git a/apps/angular/31-module-to-standalone/tsconfig.app.json b/apps/angular/31-module-to-standalone/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/31-module-to-standalone/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/module-to-standalone/tsconfig.editor.json b/apps/angular/31-module-to-standalone/tsconfig.editor.json similarity index 100% rename from apps/angular/module-to-standalone/tsconfig.editor.json rename to apps/angular/31-module-to-standalone/tsconfig.editor.json diff --git a/apps/angular/31-module-to-standalone/tsconfig.json b/apps/angular/31-module-to-standalone/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/angular/31-module-to-standalone/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/module-to-standalone/.eslintrc.json b/apps/angular/32-change-detection-bug/.eslintrc.json similarity index 100% rename from apps/angular/module-to-standalone/.eslintrc.json rename to apps/angular/32-change-detection-bug/.eslintrc.json diff --git a/apps/angular/32-change-detection-bug/README.md b/apps/angular/32-change-detection-bug/README.md new file mode 100644 index 000000000..41e533388 --- /dev/null +++ b/apps/angular/32-change-detection-bug/README.md @@ -0,0 +1,13 @@ +# Change Detection Bug + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-change-detection-bug +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/32-bug-cd/). diff --git a/apps/angular/32-change-detection-bug/jest.config.ts b/apps/angular/32-change-detection-bug/jest.config.ts new file mode 100644 index 000000000..c744feb05 --- /dev/null +++ b/apps/angular/32-change-detection-bug/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-change-detection-bug', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/32-change-detection-bug', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/32-change-detection-bug/project.json b/apps/angular/32-change-detection-bug/project.json new file mode 100644 index 000000000..977b76334 --- /dev/null +++ b/apps/angular/32-change-detection-bug/project.json @@ -0,0 +1,83 @@ +{ + "name": "angular-change-detection-bug", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/32-change-detection-bug/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/32-change-detection-bug", + "index": "apps/angular/32-change-detection-bug/src/index.html", + "main": "apps/angular/32-change-detection-bug/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/32-change-detection-bug/tsconfig.app.json", + "assets": [ + "apps/angular/32-change-detection-bug/src/favicon.ico", + "apps/angular/32-change-detection-bug/src/assets" + ], + "styles": ["apps/angular/32-change-detection-bug/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-change-detection-bug:build:production" + }, + "development": { + "buildTarget": "angular-change-detection-bug:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-change-detection-bug:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/32-change-detection-bug/src/app/app.component.ts b/apps/angular/32-change-detection-bug/src/app/app.component.ts new file mode 100644 index 000000000..217999c3a --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/app/app.component.ts @@ -0,0 +1,20 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` +

My Application

+
+ +
+ +
+
+ `, + host: { + class: 'flex flex-col gap-2', + }, +}) +export class AppComponent {} diff --git a/apps/angular/bug-cd/src/app/app.config.ts b/apps/angular/32-change-detection-bug/src/app/app.config.ts similarity index 100% rename from apps/angular/bug-cd/src/app/app.config.ts rename to apps/angular/32-change-detection-bug/src/app/app.config.ts diff --git a/apps/angular/bug-cd/src/app/bar.component.ts b/apps/angular/32-change-detection-bug/src/app/bar.component.ts similarity index 88% rename from apps/angular/bug-cd/src/app/bar.component.ts rename to apps/angular/32-change-detection-bug/src/app/bar.component.ts index b7a53924e..81981f99d 100644 --- a/apps/angular/bug-cd/src/app/bar.component.ts +++ b/apps/angular/32-change-detection-bug/src/app/bar.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; + @Component({ selector: 'app-bar', - standalone: true, template: ` BarComponent `, diff --git a/apps/angular/bug-cd/src/app/fake.service.ts b/apps/angular/32-change-detection-bug/src/app/fake.service.ts similarity index 100% rename from apps/angular/bug-cd/src/app/fake.service.ts rename to apps/angular/32-change-detection-bug/src/app/fake.service.ts diff --git a/apps/angular/32-change-detection-bug/src/app/foo.component.ts b/apps/angular/32-change-detection-bug/src/app/foo.component.ts new file mode 100644 index 000000000..1fcb24326 --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/app/foo.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-foo', + template: ` + Foo Component + `, +}) +export class FooComponent {} diff --git a/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts b/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts new file mode 100644 index 000000000..1a3a5e93a --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts @@ -0,0 +1,63 @@ +import { Component, inject, input } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { RouterLink, RouterLinkActive } from '@angular/router'; +import { FakeServiceService } from './fake.service'; + +interface MenuItem { + path: string; + name: string; +} + +@Component({ + selector: 'app-nav', + imports: [RouterLink, RouterLinkActive], + template: ` + @for (menu of menus(); track menu.path) { + + {{ menu.name }} + + } + `, + styles: [ + ` + a.isSelected { + @apply bg-gray-600 text-white; + } + `, + ], + host: { + class: 'flex flex-col p-2 gap-2', + }, +}) +export class NavigationComponent { + menus = input.required(); +} + +@Component({ + imports: [NavigationComponent], + template: ` + @if (info() !== null) { + + } @else { + + } + `, + host: {}, +}) +export class MainNavigationComponent { + private fakeBackend = inject(FakeServiceService); + + readonly info = toSignal(this.fakeBackend.getInfoFromBackend(), { + initialValue: null, + }); + + getMenu(prop: string) { + return [ + { path: '/foo', name: `Foo ${prop}` }, + { path: '/bar', name: `Bar ${prop}` }, + ]; + } +} diff --git a/apps/angular/module-to-standalone/src/assets/.gitkeep b/apps/angular/32-change-detection-bug/src/assets/.gitkeep similarity index 100% rename from apps/angular/module-to-standalone/src/assets/.gitkeep rename to apps/angular/32-change-detection-bug/src/assets/.gitkeep diff --git a/apps/angular/interop-rxjs-signal/src/favicon.ico b/apps/angular/32-change-detection-bug/src/favicon.ico similarity index 100% rename from apps/angular/interop-rxjs-signal/src/favicon.ico rename to apps/angular/32-change-detection-bug/src/favicon.ico diff --git a/apps/angular/32-change-detection-bug/src/index.html b/apps/angular/32-change-detection-bug/src/index.html new file mode 100644 index 000000000..350759387 --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-change-detection-bug + + + + + + + + diff --git a/apps/angular/32-change-detection-bug/src/main.ts b/apps/angular/32-change-detection-bug/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/decoupling/src/styles.scss b/apps/angular/32-change-detection-bug/src/styles.scss similarity index 100% rename from apps/angular/decoupling/src/styles.scss rename to apps/angular/32-change-detection-bug/src/styles.scss diff --git a/apps/angular/32-change-detection-bug/src/test-setup.ts b/apps/angular/32-change-detection-bug/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/32-change-detection-bug/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/decoupling/tailwind.config.js b/apps/angular/32-change-detection-bug/tailwind.config.js similarity index 100% rename from apps/angular/decoupling/tailwind.config.js rename to apps/angular/32-change-detection-bug/tailwind.config.js diff --git a/apps/angular/32-change-detection-bug/tsconfig.app.json b/apps/angular/32-change-detection-bug/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/32-change-detection-bug/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/bug-cd/tsconfig.editor.json b/apps/angular/32-change-detection-bug/tsconfig.editor.json similarity index 100% rename from apps/angular/bug-cd/tsconfig.editor.json rename to apps/angular/32-change-detection-bug/tsconfig.editor.json diff --git a/apps/angular/32-change-detection-bug/tsconfig.json b/apps/angular/32-change-detection-bug/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/angular/32-change-detection-bug/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/32-change-detection-bug/tsconfig.spec.json b/apps/angular/32-change-detection-bug/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/angular/32-change-detection-bug/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/router-input/.eslintrc.json b/apps/angular/33-decoupling-components/.eslintrc.json similarity index 100% rename from apps/angular/router-input/.eslintrc.json rename to apps/angular/33-decoupling-components/.eslintrc.json diff --git a/apps/angular/33-decoupling-components/README.md b/apps/angular/33-decoupling-components/README.md new file mode 100644 index 000000000..4af70458f --- /dev/null +++ b/apps/angular/33-decoupling-components/README.md @@ -0,0 +1,13 @@ +# Decoupling Components + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-decoupling-components +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/33-decoupling/). diff --git a/apps/angular/33-decoupling-components/project.json b/apps/angular/33-decoupling-components/project.json new file mode 100644 index 000000000..c4140b61b --- /dev/null +++ b/apps/angular/33-decoupling-components/project.json @@ -0,0 +1,72 @@ +{ + "name": "angular-decoupling-components", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/33-decoupling-components/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/33-decoupling-components", + "index": "apps/angular/33-decoupling-components/src/index.html", + "main": "apps/angular/33-decoupling-components/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/33-decoupling-components/tsconfig.app.json", + "assets": [ + "apps/angular/33-decoupling-components/src/favicon.ico", + "apps/angular/33-decoupling-components/src/assets" + ], + "styles": ["apps/angular/33-decoupling-components/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-decoupling-components:build:production" + }, + "development": { + "buildTarget": "angular-decoupling-components:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-decoupling-components:build" + } + } + } +} diff --git a/apps/angular/33-decoupling-components/src/app/app.component.ts b/apps/angular/33-decoupling-components/src/app/app.component.ts new file mode 100644 index 000000000..0d78f4d34 --- /dev/null +++ b/apps/angular/33-decoupling-components/src/app/app.component.ts @@ -0,0 +1,12 @@ +import { BtnDisabledDirective } from '@angular-challenges/decoupling/brain'; +import { BtnHelmetDirective } from '@angular-challenges/decoupling/helmet'; +import { Component } from '@angular/core'; + +@Component({ + imports: [BtnDisabledDirective, BtnHelmetDirective], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent {} diff --git a/apps/angular/ngfor-enhancement/src/assets/.gitkeep b/apps/angular/33-decoupling-components/src/assets/.gitkeep similarity index 100% rename from apps/angular/ngfor-enhancement/src/assets/.gitkeep rename to apps/angular/33-decoupling-components/src/assets/.gitkeep diff --git a/apps/angular/module-to-standalone/src/favicon.ico b/apps/angular/33-decoupling-components/src/favicon.ico similarity index 100% rename from apps/angular/module-to-standalone/src/favicon.ico rename to apps/angular/33-decoupling-components/src/favicon.ico diff --git a/apps/angular/33-decoupling-components/src/index.html b/apps/angular/33-decoupling-components/src/index.html new file mode 100644 index 000000000..b946b0cfd --- /dev/null +++ b/apps/angular/33-decoupling-components/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-decoupling-components + + + + + + + + diff --git a/apps/angular/33-decoupling-components/src/main.ts b/apps/angular/33-decoupling-components/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/33-decoupling-components/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/injection-token/src/styles.scss b/apps/angular/33-decoupling-components/src/styles.scss similarity index 100% rename from apps/angular/injection-token/src/styles.scss rename to apps/angular/33-decoupling-components/src/styles.scss diff --git a/apps/angular/injection-token/tailwind.config.js b/apps/angular/33-decoupling-components/tailwind.config.js similarity index 100% rename from apps/angular/injection-token/tailwind.config.js rename to apps/angular/33-decoupling-components/tailwind.config.js diff --git a/apps/angular/33-decoupling-components/tsconfig.app.json b/apps/angular/33-decoupling-components/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/33-decoupling-components/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/decoupling/tsconfig.editor.json b/apps/angular/33-decoupling-components/tsconfig.editor.json similarity index 100% rename from apps/angular/decoupling/tsconfig.editor.json rename to apps/angular/33-decoupling-components/tsconfig.editor.json diff --git a/apps/angular/33-decoupling-components/tsconfig.json b/apps/angular/33-decoupling-components/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/angular/33-decoupling-components/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/injection-token/.eslintrc.json b/apps/angular/39-injection-token/.eslintrc.json similarity index 100% rename from apps/angular/injection-token/.eslintrc.json rename to apps/angular/39-injection-token/.eslintrc.json diff --git a/apps/angular/injection-token/README.md b/apps/angular/39-injection-token/README.md similarity index 100% rename from apps/angular/injection-token/README.md rename to apps/angular/39-injection-token/README.md diff --git a/apps/angular/39-injection-token/jest.config.ts b/apps/angular/39-injection-token/jest.config.ts new file mode 100644 index 000000000..22267ad25 --- /dev/null +++ b/apps/angular/39-injection-token/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-injection-token', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/39-injection-token', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/39-injection-token/project.json b/apps/angular/39-injection-token/project.json new file mode 100644 index 000000000..135c0c0f6 --- /dev/null +++ b/apps/angular/39-injection-token/project.json @@ -0,0 +1,83 @@ +{ + "name": "angular-injection-token", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/39-injection-token/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/39-injection-token", + "index": "apps/angular/39-injection-token/src/index.html", + "main": "apps/angular/39-injection-token/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/39-injection-token/tsconfig.app.json", + "assets": [ + "apps/angular/39-injection-token/src/favicon.ico", + "apps/angular/39-injection-token/src/assets" + ], + "styles": ["apps/angular/39-injection-token/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-injection-token:build:production" + }, + "development": { + "buildTarget": "angular-injection-token:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-injection-token:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/39-injection-token/src/app/app.component.ts b/apps/angular/39-injection-token/src/app/app.component.ts new file mode 100644 index 000000000..280dc090a --- /dev/null +++ b/apps/angular/39-injection-token/src/app/app.component.ts @@ -0,0 +1,22 @@ +import { Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + template: ` +
+ + +
+ + `, + host: { + class: 'p-10 flex flex-col', + }, +}) +export class AppComponent {} diff --git a/apps/angular/injection-token/src/app/app.config.ts b/apps/angular/39-injection-token/src/app/app.config.ts similarity index 100% rename from apps/angular/injection-token/src/app/app.config.ts rename to apps/angular/39-injection-token/src/app/app.config.ts diff --git a/apps/angular/injection-token/src/app/data.ts b/apps/angular/39-injection-token/src/app/data.ts similarity index 100% rename from apps/angular/injection-token/src/app/data.ts rename to apps/angular/39-injection-token/src/app/data.ts diff --git a/apps/angular/injection-token/src/app/phone.component.ts b/apps/angular/39-injection-token/src/app/phone.component.ts similarity index 95% rename from apps/angular/injection-token/src/app/phone.component.ts rename to apps/angular/39-injection-token/src/app/phone.component.ts index a58b3cd99..41ee3cfc0 100644 --- a/apps/angular/injection-token/src/app/phone.component.ts +++ b/apps/angular/39-injection-token/src/app/phone.component.ts @@ -3,7 +3,6 @@ import { TimerContainerComponent } from './timer-container.component'; @Component({ selector: 'app-phone', - standalone: true, imports: [TimerContainerComponent], template: `
diff --git a/apps/angular/injection-token/src/app/timer-container.component.ts b/apps/angular/39-injection-token/src/app/timer-container.component.ts similarity index 96% rename from apps/angular/injection-token/src/app/timer-container.component.ts rename to apps/angular/39-injection-token/src/app/timer-container.component.ts index 30af69354..67db6059a 100644 --- a/apps/angular/injection-token/src/app/timer-container.component.ts +++ b/apps/angular/39-injection-token/src/app/timer-container.component.ts @@ -3,7 +3,6 @@ import { DEFAULT_TIMER } from './data'; import { TimerComponent } from './timer.component'; @Component({ selector: 'timer-container', - standalone: true, imports: [TimerComponent], template: `
diff --git a/apps/angular/injection-token/src/app/timer.component.ts b/apps/angular/39-injection-token/src/app/timer.component.ts similarity index 94% rename from apps/angular/injection-token/src/app/timer.component.ts rename to apps/angular/39-injection-token/src/app/timer.component.ts index 95707ec61..335a077bf 100644 --- a/apps/angular/injection-token/src/app/timer.component.ts +++ b/apps/angular/39-injection-token/src/app/timer.component.ts @@ -5,7 +5,6 @@ import { DEFAULT_TIMER } from './data'; @Component({ selector: 'timer', - standalone: true, template: ` Timer running {{ timer() }} `, diff --git a/apps/angular/injection-token/src/app/video.component.ts b/apps/angular/39-injection-token/src/app/video.component.ts similarity index 95% rename from apps/angular/injection-token/src/app/video.component.ts rename to apps/angular/39-injection-token/src/app/video.component.ts index 2c218071a..ba0a218b4 100644 --- a/apps/angular/injection-token/src/app/video.component.ts +++ b/apps/angular/39-injection-token/src/app/video.component.ts @@ -3,7 +3,6 @@ import { TimerContainerComponent } from './timer-container.component'; @Component({ selector: 'app-video', - standalone: true, imports: [TimerContainerComponent], template: `
diff --git a/apps/angular/permissions/src/assets/.gitkeep b/apps/angular/39-injection-token/src/assets/.gitkeep similarity index 100% rename from apps/angular/permissions/src/assets/.gitkeep rename to apps/angular/39-injection-token/src/assets/.gitkeep diff --git a/apps/angular/ngfor-enhancement/src/favicon.ico b/apps/angular/39-injection-token/src/favicon.ico similarity index 100% rename from apps/angular/ngfor-enhancement/src/favicon.ico rename to apps/angular/39-injection-token/src/favicon.ico diff --git a/apps/angular/injection-token/src/index.html b/apps/angular/39-injection-token/src/index.html similarity index 100% rename from apps/angular/injection-token/src/index.html rename to apps/angular/39-injection-token/src/index.html diff --git a/apps/angular/39-injection-token/src/main.ts b/apps/angular/39-injection-token/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/39-injection-token/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/interop-rxjs-signal/src/styles.scss b/apps/angular/39-injection-token/src/styles.scss similarity index 100% rename from apps/angular/interop-rxjs-signal/src/styles.scss rename to apps/angular/39-injection-token/src/styles.scss diff --git a/apps/angular/39-injection-token/src/test-setup.ts b/apps/angular/39-injection-token/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/39-injection-token/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/interop-rxjs-signal/tailwind.config.js b/apps/angular/39-injection-token/tailwind.config.js similarity index 100% rename from apps/angular/interop-rxjs-signal/tailwind.config.js rename to apps/angular/39-injection-token/tailwind.config.js diff --git a/apps/angular/39-injection-token/tsconfig.app.json b/apps/angular/39-injection-token/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/39-injection-token/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/injection-token/tsconfig.editor.json b/apps/angular/39-injection-token/tsconfig.editor.json similarity index 100% rename from apps/angular/injection-token/tsconfig.editor.json rename to apps/angular/39-injection-token/tsconfig.editor.json diff --git a/apps/angular/39-injection-token/tsconfig.json b/apps/angular/39-injection-token/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/angular/39-injection-token/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/39-injection-token/tsconfig.spec.json b/apps/angular/39-injection-token/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/angular/39-injection-token/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/context-outlet-type/.eslintrc.json b/apps/angular/4-typed-context-outlet/.eslintrc.json similarity index 100% rename from apps/angular/context-outlet-type/.eslintrc.json rename to apps/angular/4-typed-context-outlet/.eslintrc.json diff --git a/apps/angular/4-typed-context-outlet/README.md b/apps/angular/4-typed-context-outlet/README.md new file mode 100644 index 000000000..e81915167 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/README.md @@ -0,0 +1,13 @@ +# Typed ContextOutlet + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-typed-context-outlet +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/4-context-outlet-typed/). diff --git a/apps/angular/4-typed-context-outlet/project.json b/apps/angular/4-typed-context-outlet/project.json new file mode 100644 index 000000000..273bca97d --- /dev/null +++ b/apps/angular/4-typed-context-outlet/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-typed-context-outlet", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/4-typed-context-outlet/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/4-typed-context-outlet", + "index": "apps/angular/4-typed-context-outlet/src/index.html", + "main": "apps/angular/4-typed-context-outlet/src/main.ts", + "polyfills": "apps/angular/4-typed-context-outlet/src/polyfills.ts", + "tsConfig": "apps/angular/4-typed-context-outlet/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/4-typed-context-outlet/src/favicon.ico", + "apps/angular/4-typed-context-outlet/src/assets" + ], + "styles": ["apps/angular/4-typed-context-outlet/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-typed-context-outlet:build:production" + }, + "development": { + "buildTarget": "angular-typed-context-outlet:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-typed-context-outlet:build" + } + } + } +} diff --git a/apps/angular/4-typed-context-outlet/src/app/app.component.ts b/apps/angular/4-typed-context-outlet/src/app/app.component.ts new file mode 100644 index 000000000..d608bec2c --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/app.component.ts @@ -0,0 +1,44 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ListComponent } from './list.component'; +import { PersonComponent } from './person.component'; + +@Component({ + imports: [PersonComponent, ListComponent], + selector: 'app-root', + template: ` + + + {{ name }}: {{ age }} + + + + + + {{ student.name }}: {{ student.age }} - {{ i }} + + + + + + {{ city.name }}: {{ city.country }} - {{ i }} + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + person = { + name: 'toto', + age: 3, + }; + + students = [ + { name: 'toto', age: 3 }, + { name: 'titi', age: 4 }, + ]; + + cities = [ + { name: 'Paris', country: 'France' }, + { name: 'Berlin', country: 'Germany' }, + ]; +} diff --git a/apps/angular/4-typed-context-outlet/src/app/list.component.ts b/apps/angular/4-typed-context-outlet/src/app/list.component.ts new file mode 100644 index 000000000..57fa4e361 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/list.component.ts @@ -0,0 +1,30 @@ +import { NgTemplateOutlet } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + contentChild, + input, + TemplateRef, +} from '@angular/core'; + +@Component({ + selector: 'list', + template: ` + @for (item of list(); track $index) { + + } + + No Template + `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [NgTemplateOutlet], +}) +export class ListComponent { + list = input.required(); + + listTemplateRef = contentChild('listRef', { read: TemplateRef }); +} diff --git a/apps/angular/4-typed-context-outlet/src/app/person.component.ts b/apps/angular/4-typed-context-outlet/src/app/person.component.ts new file mode 100644 index 000000000..d9f5e7520 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/person.component.ts @@ -0,0 +1,21 @@ +import { NgTemplateOutlet } from '@angular/common'; +import { Component, contentChild, input, TemplateRef } from '@angular/core'; + +@Component({ + imports: [NgTemplateOutlet], + selector: 'person', + template: ` + + + No Template + `, +}) +export class PersonComponent { + person = input.required<{ name: string; age: number }>(); + + personTemplateRef = contentChild('personRef', { read: TemplateRef }); +} diff --git a/apps/angular/permissions/src/favicon.ico b/apps/angular/4-typed-context-outlet/src/favicon.ico similarity index 100% rename from apps/angular/permissions/src/favicon.ico rename to apps/angular/4-typed-context-outlet/src/favicon.ico diff --git a/apps/angular/4-typed-context-outlet/src/index.html b/apps/angular/4-typed-context-outlet/src/index.html new file mode 100644 index 000000000..a9c0b5484 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-typed-context-outlet + + + + + + + + diff --git a/apps/angular/4-typed-context-outlet/src/main.ts b/apps/angular/4-typed-context-outlet/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/ngfor-enhancement/src/polyfills.ts b/apps/angular/4-typed-context-outlet/src/polyfills.ts similarity index 100% rename from apps/angular/ngfor-enhancement/src/polyfills.ts rename to apps/angular/4-typed-context-outlet/src/polyfills.ts diff --git a/apps/angular/pipe-hard/src/styles.scss b/apps/angular/4-typed-context-outlet/src/styles.scss similarity index 100% rename from apps/angular/pipe-hard/src/styles.scss rename to apps/angular/4-typed-context-outlet/src/styles.scss diff --git a/apps/angular/4-typed-context-outlet/tsconfig.app.json b/apps/angular/4-typed-context-outlet/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/4-typed-context-outlet/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/crud/tsconfig.editor.json b/apps/angular/4-typed-context-outlet/tsconfig.editor.json similarity index 100% rename from apps/angular/crud/tsconfig.editor.json rename to apps/angular/4-typed-context-outlet/tsconfig.editor.json diff --git a/apps/angular/4-typed-context-outlet/tsconfig.json b/apps/angular/4-typed-context-outlet/tsconfig.json new file mode 100644 index 000000000..f512037ca --- /dev/null +++ b/apps/angular/4-typed-context-outlet/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/view-transition/.eslintrc.json b/apps/angular/44-view-transition/.eslintrc.json similarity index 100% rename from apps/angular/view-transition/.eslintrc.json rename to apps/angular/44-view-transition/.eslintrc.json diff --git a/apps/angular/view-transition/README.md b/apps/angular/44-view-transition/README.md similarity index 100% rename from apps/angular/view-transition/README.md rename to apps/angular/44-view-transition/README.md diff --git a/apps/angular/44-view-transition/project.json b/apps/angular/44-view-transition/project.json new file mode 100644 index 000000000..4104b5de9 --- /dev/null +++ b/apps/angular/44-view-transition/project.json @@ -0,0 +1,70 @@ +{ + "name": "angular-view-transition", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/44-view-transition/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/44-view-transition", + "index": "apps/angular/44-view-transition/src/index.html", + "browser": "apps/angular/44-view-transition/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/44-view-transition/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/44-view-transition/src/favicon.ico", + "apps/angular/44-view-transition/src/assets" + ], + "styles": ["apps/angular/44-view-transition/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-view-transition:build:production" + }, + "development": { + "buildTarget": "angular-view-transition:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-view-transition:build" + } + } + } +} diff --git a/apps/angular/44-view-transition/src/app/app.component.ts b/apps/angular/44-view-transition/src/app/app.component.ts new file mode 100644 index 000000000..1fcb0c548 --- /dev/null +++ b/apps/angular/44-view-transition/src/app/app.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/view-transition/src/app/app.config.ts b/apps/angular/44-view-transition/src/app/app.config.ts similarity index 100% rename from apps/angular/view-transition/src/app/app.config.ts rename to apps/angular/44-view-transition/src/app/app.config.ts diff --git a/apps/angular/view-transition/src/app/blog/blog.component.ts b/apps/angular/44-view-transition/src/app/blog/blog.component.ts similarity index 97% rename from apps/angular/view-transition/src/app/blog/blog.component.ts rename to apps/angular/44-view-transition/src/app/blog/blog.component.ts index 68ffcde50..29291d21e 100644 --- a/apps/angular/view-transition/src/app/blog/blog.component.ts +++ b/apps/angular/44-view-transition/src/app/blog/blog.component.ts @@ -4,7 +4,6 @@ import { ThumbnailComponent } from './thumbnail.component'; @Component({ selector: 'blog', - standalone: true, imports: [ThumbnailComponent], template: `
diff --git a/apps/angular/view-transition/src/app/blog/thumbnail.component.ts b/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts similarity index 98% rename from apps/angular/view-transition/src/app/blog/thumbnail.component.ts rename to apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts index 6263e97ab..dd2e25e26 100644 --- a/apps/angular/view-transition/src/app/blog/thumbnail.component.ts +++ b/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts @@ -6,7 +6,6 @@ import { ThumbnailHeaderComponent } from './thumbnail-header.component'; @Component({ selector: 'blog-thumbnail', - standalone: true, imports: [NgOptimizedImage, ThumbnailHeaderComponent, RouterLinkWithHref], template: ` diff --git a/apps/angular/view-transition/src/app/data.ts b/apps/angular/44-view-transition/src/app/data.ts similarity index 100% rename from apps/angular/view-transition/src/app/data.ts rename to apps/angular/44-view-transition/src/app/data.ts diff --git a/apps/angular/view-transition/src/app/post.model.ts b/apps/angular/44-view-transition/src/app/post.model.ts similarity index 100% rename from apps/angular/view-transition/src/app/post.model.ts rename to apps/angular/44-view-transition/src/app/post.model.ts diff --git a/apps/angular/view-transition/src/app/post/post-header.component.ts b/apps/angular/44-view-transition/src/app/post/post-header.component.ts similarity index 97% rename from apps/angular/view-transition/src/app/post/post-header.component.ts rename to apps/angular/44-view-transition/src/app/post/post-header.component.ts index 8b62a6c48..6d5f30e54 100644 --- a/apps/angular/view-transition/src/app/post/post-header.component.ts +++ b/apps/angular/44-view-transition/src/app/post/post-header.component.ts @@ -3,7 +3,6 @@ import { Component, input } from '@angular/core'; @Component({ selector: 'post-header', - standalone: true, imports: [NgOptimizedImage], template: `
diff --git a/apps/angular/44-view-transition/src/app/post/post.component.ts b/apps/angular/44-view-transition/src/app/post/post.component.ts new file mode 100644 index 000000000..edb87f780 --- /dev/null +++ b/apps/angular/44-view-transition/src/app/post/post.component.ts @@ -0,0 +1,46 @@ +import { NgOptimizedImage } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + computed, + input, +} from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { ThumbnailHeaderComponent } from '../blog/thumbnail-header.component'; +import { fakeTextChapters, posts } from '../data'; +import { PostHeaderComponent } from './post-header.component'; + +@Component({ + selector: 'post', + imports: [ + ThumbnailHeaderComponent, + NgOptimizedImage, + PostHeaderComponent, + RouterLink, + ], + template: ` +
+ + +

{{ post().title }}

+ + @for (chapter of fakeTextChapter; track $index) { +

{{ chapter }}

+ } +
+ `, + host: { + class: 'flex h-full justify-center', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class PostComponent { + id = input.required(); + post = computed(() => posts.filter((p) => p.id === this.id())[0]); + + fakeTextChapter = fakeTextChapters; +} diff --git a/apps/angular/pipe-easy/src/assets/.gitkeep b/apps/angular/44-view-transition/src/assets/.gitkeep similarity index 100% rename from apps/angular/pipe-easy/src/assets/.gitkeep rename to apps/angular/44-view-transition/src/assets/.gitkeep diff --git a/apps/angular/view-transition/src/assets/angular.webp b/apps/angular/44-view-transition/src/assets/angular.webp similarity index 100% rename from apps/angular/view-transition/src/assets/angular.webp rename to apps/angular/44-view-transition/src/assets/angular.webp diff --git a/apps/angular/view-transition/src/assets/guard.full.webp b/apps/angular/44-view-transition/src/assets/guard.full.webp similarity index 100% rename from apps/angular/view-transition/src/assets/guard.full.webp rename to apps/angular/44-view-transition/src/assets/guard.full.webp diff --git a/apps/angular/view-transition/src/assets/highly-custom.full.webp b/apps/angular/44-view-transition/src/assets/highly-custom.full.webp similarity index 100% rename from apps/angular/view-transition/src/assets/highly-custom.full.webp rename to apps/angular/44-view-transition/src/assets/highly-custom.full.webp diff --git a/apps/angular/view-transition/src/assets/profil.webp b/apps/angular/44-view-transition/src/assets/profil.webp similarity index 100% rename from apps/angular/view-transition/src/assets/profil.webp rename to apps/angular/44-view-transition/src/assets/profil.webp diff --git a/apps/angular/view-transition/src/assets/signal-cd.full.webp b/apps/angular/44-view-transition/src/assets/signal-cd.full.webp similarity index 100% rename from apps/angular/view-transition/src/assets/signal-cd.full.webp rename to apps/angular/44-view-transition/src/assets/signal-cd.full.webp diff --git a/apps/angular/pipe-easy/src/favicon.ico b/apps/angular/44-view-transition/src/favicon.ico similarity index 100% rename from apps/angular/pipe-easy/src/favicon.ico rename to apps/angular/44-view-transition/src/favicon.ico diff --git a/apps/angular/view-transition/src/index.html b/apps/angular/44-view-transition/src/index.html similarity index 100% rename from apps/angular/view-transition/src/index.html rename to apps/angular/44-view-transition/src/index.html diff --git a/apps/angular/44-view-transition/src/main.ts b/apps/angular/44-view-transition/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/44-view-transition/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/44-view-transition/src/styles.scss b/apps/angular/44-view-transition/src/styles.scss new file mode 100644 index 000000000..b5c61c956 --- /dev/null +++ b/apps/angular/44-view-transition/src/styles.scss @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/angular/permissions/tailwind.config.js b/apps/angular/44-view-transition/tailwind.config.js similarity index 100% rename from apps/angular/permissions/tailwind.config.js rename to apps/angular/44-view-transition/tailwind.config.js diff --git a/apps/angular/44-view-transition/tsconfig.app.json b/apps/angular/44-view-transition/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/44-view-transition/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/styling/tsconfig.editor.json b/apps/angular/44-view-transition/tsconfig.editor.json similarity index 100% rename from apps/angular/styling/tsconfig.editor.json rename to apps/angular/44-view-transition/tsconfig.editor.json diff --git a/apps/angular/44-view-transition/tsconfig.json b/apps/angular/44-view-transition/tsconfig.json new file mode 100644 index 000000000..7cfcc3b0b --- /dev/null +++ b/apps/angular/44-view-transition/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/ngfor-enhancement/.eslintrc.json b/apps/angular/45-react-in-angular/.eslintrc.json similarity index 100% rename from apps/angular/ngfor-enhancement/.eslintrc.json rename to apps/angular/45-react-in-angular/.eslintrc.json diff --git a/apps/angular/react-in-angular/README.md b/apps/angular/45-react-in-angular/README.md similarity index 100% rename from apps/angular/react-in-angular/README.md rename to apps/angular/45-react-in-angular/README.md diff --git a/apps/angular/45-react-in-angular/jest.config.ts b/apps/angular/45-react-in-angular/jest.config.ts new file mode 100644 index 000000000..1d0a369b3 --- /dev/null +++ b/apps/angular/45-react-in-angular/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-react-in-angular', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/45-react-in-angular', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/45-react-in-angular/project.json b/apps/angular/45-react-in-angular/project.json new file mode 100644 index 000000000..8a3bf02fc --- /dev/null +++ b/apps/angular/45-react-in-angular/project.json @@ -0,0 +1,81 @@ +{ + "name": "angular-react-in-angular", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/45-react-in-angular/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/45-react-in-angular", + "index": "apps/angular/45-react-in-angular/src/index.html", + "browser": "apps/angular/45-react-in-angular/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/45-react-in-angular/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/45-react-in-angular/src/favicon.ico", + "apps/angular/45-react-in-angular/src/assets" + ], + "styles": ["apps/angular/45-react-in-angular/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-react-in-angular:build:production" + }, + "development": { + "buildTarget": "angular-react-in-angular:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-react-in-angular:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/45-react-in-angular/src/app/app.component.ts b/apps/angular/45-react-in-angular/src/app/app.component.ts new file mode 100644 index 000000000..87b9675cc --- /dev/null +++ b/apps/angular/45-react-in-angular/src/app/app.component.ts @@ -0,0 +1,61 @@ +import { Component, signal } from '@angular/core'; +import { PostComponent } from './react/post.component'; + +type Post = { title: string; description: string }; + +@Component({ + imports: [PostComponent], + selector: 'app-root', + template: ` +
+
+ @for (post of posts; track post.title) { +
+ +
+ } +
+
+ Selected Post: + + {{ selectedPost()?.title ?? '-' }} + +
+
+ `, + styles: [''], +}) +export class AppComponent { + readonly posts = [ + { + title: 'A Deep Dive into Angular', + description: + "Explore Angular's core features, its evolution, and best practices in development for creating dynamic, efficient web applications in our comprehensive guide.", + pictureLink: + 'https://images.unsplash.com/photo-1471958680802-1345a694ba6d', + }, + { + title: 'The Perfect Combination', + description: + 'Unveil the power of combining Angular & React in web development, maximizing efficiency and flexibility for building scalable, sophisticated applications.', + pictureLink: + 'https://images.unsplash.com/photo-1518717202715-9fa9d099f58a', + }, + { + title: 'Taking Angular to the Next Level', + description: + "Discover how integrating React with Angular elevates web development, blending Angular's structure with React's UI prowess for advanced applications.", + pictureLink: + 'https://images.unsplash.com/photo-1532103050105-860af53bc6aa', + }, + ]; + + readonly selectedPost = signal(null); + + selectPost(post: Post) { + this.selectedPost.set(post); + } +} diff --git a/apps/angular/react-in-angular/src/app/app.config.ts b/apps/angular/45-react-in-angular/src/app/app.config.ts similarity index 100% rename from apps/angular/react-in-angular/src/app/app.config.ts rename to apps/angular/45-react-in-angular/src/app/app.config.ts diff --git a/apps/angular/45-react-in-angular/src/app/react/ReactPost.tsx b/apps/angular/45-react-in-angular/src/app/react/ReactPost.tsx new file mode 100644 index 000000000..3f6b9e4cd --- /dev/null +++ b/apps/angular/45-react-in-angular/src/app/react/ReactPost.tsx @@ -0,0 +1,29 @@ +// import React from 'react'; + +export default function ReactPost(props: { + title?: string; + description?: string; + pictureLink?: string; + selected?: boolean; + handleClick: () => void; +}) { + return ( +
+
+ {props.title} +
+
{props.title}
+

{props.description}

+ +
+
+
+ ); +} diff --git a/apps/angular/45-react-in-angular/src/app/react/post.component.ts b/apps/angular/45-react-in-angular/src/app/react/post.component.ts new file mode 100644 index 000000000..d5eb2cedf --- /dev/null +++ b/apps/angular/45-react-in-angular/src/app/react/post.component.ts @@ -0,0 +1,16 @@ +import { Component, EventEmitter, input, Output } from '@angular/core'; + +type Post = { title: string; description: string; pictureLink: string }; + +@Component({ + selector: 'app-post', + template: ` +
+ `, + styles: [''], +}) +export class PostComponent { + post = input(undefined); + isSelected = input(false); + @Output() selectPost = new EventEmitter(); +} diff --git a/apps/angular/pipe-hard/src/assets/.gitkeep b/apps/angular/45-react-in-angular/src/assets/.gitkeep similarity index 100% rename from apps/angular/pipe-hard/src/assets/.gitkeep rename to apps/angular/45-react-in-angular/src/assets/.gitkeep diff --git a/apps/angular/pipe-hard/src/favicon.ico b/apps/angular/45-react-in-angular/src/favicon.ico similarity index 100% rename from apps/angular/pipe-hard/src/favicon.ico rename to apps/angular/45-react-in-angular/src/favicon.ico diff --git a/apps/angular/react-in-angular/src/index.html b/apps/angular/45-react-in-angular/src/index.html similarity index 100% rename from apps/angular/react-in-angular/src/index.html rename to apps/angular/45-react-in-angular/src/index.html diff --git a/apps/angular/45-react-in-angular/src/main.ts b/apps/angular/45-react-in-angular/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/45-react-in-angular/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/module-to-standalone/src/styles.scss b/apps/angular/45-react-in-angular/src/styles.scss similarity index 100% rename from apps/angular/module-to-standalone/src/styles.scss rename to apps/angular/45-react-in-angular/src/styles.scss diff --git a/apps/angular/45-react-in-angular/src/test-setup.ts b/apps/angular/45-react-in-angular/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/45-react-in-angular/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/projection/tailwind.config.js b/apps/angular/45-react-in-angular/tailwind.config.js similarity index 100% rename from apps/angular/projection/tailwind.config.js rename to apps/angular/45-react-in-angular/tailwind.config.js diff --git a/apps/angular/45-react-in-angular/tsconfig.app.json b/apps/angular/45-react-in-angular/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/45-react-in-angular/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/interop-rxjs-signal/tsconfig.editor.json b/apps/angular/45-react-in-angular/tsconfig.editor.json similarity index 100% rename from apps/angular/interop-rxjs-signal/tsconfig.editor.json rename to apps/angular/45-react-in-angular/tsconfig.editor.json diff --git a/apps/angular/45-react-in-angular/tsconfig.json b/apps/angular/45-react-in-angular/tsconfig.json new file mode 100644 index 000000000..0b35460df --- /dev/null +++ b/apps/angular/45-react-in-angular/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/45-react-in-angular/tsconfig.spec.json b/apps/angular/45-react-in-angular/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/angular/45-react-in-angular/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/permissions/.eslintrc.json b/apps/angular/46-simple-animations/.eslintrc.json similarity index 100% rename from apps/angular/permissions/.eslintrc.json rename to apps/angular/46-simple-animations/.eslintrc.json diff --git a/apps/angular/simple-animations/README.md b/apps/angular/46-simple-animations/README.md similarity index 100% rename from apps/angular/simple-animations/README.md rename to apps/angular/46-simple-animations/README.md diff --git a/apps/angular/46-simple-animations/jest.config.ts b/apps/angular/46-simple-animations/jest.config.ts new file mode 100644 index 000000000..c058d8afa --- /dev/null +++ b/apps/angular/46-simple-animations/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-simple-animations', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/46-simple-animations', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/46-simple-animations/project.json b/apps/angular/46-simple-animations/project.json new file mode 100644 index 000000000..34e44c7b3 --- /dev/null +++ b/apps/angular/46-simple-animations/project.json @@ -0,0 +1,81 @@ +{ + "name": "angular-simple-animations", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/46-simple-animations/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/46-simple-animations", + "index": "apps/angular/46-simple-animations/src/index.html", + "browser": "apps/angular/46-simple-animations/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/46-simple-animations/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/46-simple-animations/src/favicon.ico", + "apps/angular/46-simple-animations/src/assets" + ], + "styles": ["apps/angular/46-simple-animations/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-simple-animations:build:production" + }, + "development": { + "buildTarget": "angular-simple-animations:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-simple-animations:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/46-simple-animations/src/app/app.component.ts b/apps/angular/46-simple-animations/src/app/app.component.ts new file mode 100644 index 000000000..ae63db419 --- /dev/null +++ b/apps/angular/46-simple-animations/src/app/app.component.ts @@ -0,0 +1,87 @@ +import { Component } from '@angular/core'; + +@Component({ + imports: [], + selector: 'app-root', + styles: ` + section { + @apply flex flex-1 flex-col gap-5; + } + + .list-item { + @apply flex flex-row border-b px-5 pb-2; + + span { + @apply flex-1; + } + } + `, + template: ` +
+
+
+

2008

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae + mollitia sequi accusantium, distinctio similique laudantium eveniet + quidem sit placeat possimus tempore dolorum inventore corporis atque + quae ad, nobis explicabo delectus. +

+
+ +
+

2010

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae + mollitia sequi accusantium, distinctio similique laudantium eveniet + quidem sit placeat possimus tempore dolorum inventore corporis atque + quae ad, nobis explicabo delectus. +

+
+ +
+

2012

+

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae + mollitia sequi accusantium, distinctio similique laudantium eveniet + quidem sit placeat possimus tempore dolorum inventore corporis atque + quae ad, nobis explicabo delectus. +

+
+
+ +
+
+ Name: + Samuel +
+ +
+ Age: + 28 +
+ +
+ Birthdate: + 02.11.1995 +
+ +
+ City: + Berlin +
+ +
+ Language: + English +
+ +
+ Like Pizza: + Hell yeah +
+
+
+ `, +}) +export class AppComponent {} diff --git a/apps/angular/signal-input/src/app/app.config.ts b/apps/angular/46-simple-animations/src/app/app.config.ts similarity index 100% rename from apps/angular/signal-input/src/app/app.config.ts rename to apps/angular/46-simple-animations/src/app/app.config.ts diff --git a/apps/angular/pipe-intermediate/src/assets/.gitkeep b/apps/angular/46-simple-animations/src/assets/.gitkeep similarity index 100% rename from apps/angular/pipe-intermediate/src/assets/.gitkeep rename to apps/angular/46-simple-animations/src/assets/.gitkeep diff --git a/apps/angular/pipe-intermediate/src/favicon.ico b/apps/angular/46-simple-animations/src/favicon.ico similarity index 100% rename from apps/angular/pipe-intermediate/src/favicon.ico rename to apps/angular/46-simple-animations/src/favicon.ico diff --git a/apps/angular/simple-animations/src/index.html b/apps/angular/46-simple-animations/src/index.html similarity index 100% rename from apps/angular/simple-animations/src/index.html rename to apps/angular/46-simple-animations/src/index.html diff --git a/apps/angular/46-simple-animations/src/main.ts b/apps/angular/46-simple-animations/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/angular/46-simple-animations/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/permissions/src/styles.scss b/apps/angular/46-simple-animations/src/styles.scss similarity index 100% rename from apps/angular/permissions/src/styles.scss rename to apps/angular/46-simple-animations/src/styles.scss diff --git a/apps/angular/46-simple-animations/src/test-setup.ts b/apps/angular/46-simple-animations/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/46-simple-animations/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/react-in-angular/tailwind.config.js b/apps/angular/46-simple-animations/tailwind.config.js similarity index 100% rename from apps/angular/react-in-angular/tailwind.config.js rename to apps/angular/46-simple-animations/tailwind.config.js diff --git a/apps/angular/46-simple-animations/tsconfig.app.json b/apps/angular/46-simple-animations/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/46-simple-animations/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/react-in-angular/tsconfig.editor.json b/apps/angular/46-simple-animations/tsconfig.editor.json similarity index 100% rename from apps/angular/react-in-angular/tsconfig.editor.json rename to apps/angular/46-simple-animations/tsconfig.editor.json diff --git a/apps/angular/46-simple-animations/tsconfig.json b/apps/angular/46-simple-animations/tsconfig.json new file mode 100644 index 000000000..0b35460df --- /dev/null +++ b/apps/angular/46-simple-animations/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/46-simple-animations/tsconfig.spec.json b/apps/angular/46-simple-animations/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/angular/46-simple-animations/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/pipe-easy/.eslintrc.json b/apps/angular/5-crud-application/.eslintrc.json similarity index 100% rename from apps/angular/pipe-easy/.eslintrc.json rename to apps/angular/5-crud-application/.eslintrc.json diff --git a/apps/angular/5-crud-application/README.md b/apps/angular/5-crud-application/README.md new file mode 100644 index 000000000..8992014e3 --- /dev/null +++ b/apps/angular/5-crud-application/README.md @@ -0,0 +1,13 @@ +# Crud application + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-crud-application +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/5-crud/). diff --git a/apps/angular/5-crud-application/jest.config.ts b/apps/angular/5-crud-application/jest.config.ts new file mode 100644 index 000000000..6d0974dea --- /dev/null +++ b/apps/angular/5-crud-application/jest.config.ts @@ -0,0 +1,23 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-crud-application', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: {}, + coverageDirectory: '../../../coverage/apps/angular/5-crud-application', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/5-crud-application/project.json b/apps/angular/5-crud-application/project.json new file mode 100644 index 000000000..a31bd62a7 --- /dev/null +++ b/apps/angular/5-crud-application/project.json @@ -0,0 +1,88 @@ +{ + "name": "angular-crud-application", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/5-crud-application/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/5-crud-application", + "index": "apps/angular/5-crud-application/src/index.html", + "main": "apps/angular/5-crud-application/src/main.ts", + "polyfills": "apps/angular/5-crud-application/src/polyfills.ts", + "tsConfig": "apps/angular/5-crud-application/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/5-crud-application/src/favicon.ico", + "apps/angular/5-crud-application/src/assets" + ], + "styles": [ + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "apps/angular/5-crud-application/src/styles.scss" + ], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-crud-application:build:production" + }, + "development": { + "buildTarget": "angular-crud-application:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-crud-application:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/5-crud-application/src/app/app.component.ts b/apps/angular/5-crud-application/src/app/app.component.ts new file mode 100644 index 000000000..73ba0dc34 --- /dev/null +++ b/apps/angular/5-crud-application/src/app/app.component.ts @@ -0,0 +1,49 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, inject, OnInit } from '@angular/core'; +import { randText } from '@ngneat/falso'; + +@Component({ + imports: [], + selector: 'app-root', + template: ` + @for (todo of todos; track todo.id) { + {{ todo.title }} + + } + `, + styles: [], +}) +export class AppComponent implements OnInit { + private http = inject(HttpClient); + + todos!: any[]; + + ngOnInit(): void { + this.http + .get('https://jsonplaceholder.typicode.com/todos') + .subscribe((todos) => { + this.todos = todos; + }); + } + + update(todo: any) { + this.http + .put( + `https://jsonplaceholder.typicode.com/todos/${todo.id}`, + JSON.stringify({ + todo: todo.id, + title: randText(), + body: todo.body, + userId: todo.userId, + }), + { + headers: { + 'Content-type': 'application/json; charset=UTF-8', + }, + }, + ) + .subscribe((todoUpdated: any) => { + this.todos[todoUpdated.id - 1] = todoUpdated; + }); + } +} diff --git a/apps/angular/5-crud-application/src/app/app.config.ts b/apps/angular/5-crud-application/src/app/app.config.ts new file mode 100644 index 000000000..1c0c9422f --- /dev/null +++ b/apps/angular/5-crud-application/src/app/app.config.ts @@ -0,0 +1,6 @@ +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideHttpClient()], +}; diff --git a/apps/angular/projection/src/assets/.gitkeep b/apps/angular/5-crud-application/src/assets/.gitkeep similarity index 100% rename from apps/angular/projection/src/assets/.gitkeep rename to apps/angular/5-crud-application/src/assets/.gitkeep diff --git a/apps/angular/projection/src/favicon.ico b/apps/angular/5-crud-application/src/favicon.ico similarity index 100% rename from apps/angular/projection/src/favicon.ico rename to apps/angular/5-crud-application/src/favicon.ico diff --git a/apps/angular/5-crud-application/src/index.html b/apps/angular/5-crud-application/src/index.html new file mode 100644 index 000000000..b9ec0b609 --- /dev/null +++ b/apps/angular/5-crud-application/src/index.html @@ -0,0 +1,20 @@ + + + + + angular-crud-application + + + + + + + + + + + diff --git a/apps/angular/5-crud-application/src/main.ts b/apps/angular/5-crud-application/src/main.ts new file mode 100644 index 000000000..866d45959 --- /dev/null +++ b/apps/angular/5-crud-application/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { appConfig } from './app/app.config'; + +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/angular/permissions/src/polyfills.ts b/apps/angular/5-crud-application/src/polyfills.ts similarity index 100% rename from apps/angular/permissions/src/polyfills.ts rename to apps/angular/5-crud-application/src/polyfills.ts diff --git a/apps/angular/crud/src/styles.scss b/apps/angular/5-crud-application/src/styles.scss similarity index 100% rename from apps/angular/crud/src/styles.scss rename to apps/angular/5-crud-application/src/styles.scss diff --git a/apps/angular/5-crud-application/src/test-setup.ts b/apps/angular/5-crud-application/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/5-crud-application/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/5-crud-application/tsconfig.app.json b/apps/angular/5-crud-application/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/5-crud-application/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/ngfor-enhancement/tsconfig.editor.json b/apps/angular/5-crud-application/tsconfig.editor.json similarity index 100% rename from apps/angular/ngfor-enhancement/tsconfig.editor.json rename to apps/angular/5-crud-application/tsconfig.editor.json diff --git a/apps/angular/5-crud-application/tsconfig.json b/apps/angular/5-crud-application/tsconfig.json new file mode 100644 index 000000000..2e21bd713 --- /dev/null +++ b/apps/angular/5-crud-application/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/5-crud-application/tsconfig.spec.json b/apps/angular/5-crud-application/tsconfig.spec.json new file mode 100644 index 000000000..ae7e867cb --- /dev/null +++ b/apps/angular/5-crud-application/tsconfig.spec.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/apps/angular/pipe-hard/.eslintrc.json b/apps/angular/52-lazy-load-component/.eslintrc.json similarity index 100% rename from apps/angular/pipe-hard/.eslintrc.json rename to apps/angular/52-lazy-load-component/.eslintrc.json diff --git a/apps/angular/52-lazy-load-component/README.md b/apps/angular/52-lazy-load-component/README.md new file mode 100644 index 000000000..7da25f89b --- /dev/null +++ b/apps/angular/52-lazy-load-component/README.md @@ -0,0 +1,13 @@ +# lazy-load-component + +> author: lance-finney + +### Run Application + +```bash +npx nx serve angular-lazy-load-component +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/52-lazy-load-component/). diff --git a/apps/angular/52-lazy-load-component/jest.config.ts b/apps/angular/52-lazy-load-component/jest.config.ts new file mode 100644 index 000000000..319c30f9f --- /dev/null +++ b/apps/angular/52-lazy-load-component/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-lazy-load-component', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/52-lazy-load-component', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/52-lazy-load-component/project.json b/apps/angular/52-lazy-load-component/project.json new file mode 100644 index 000000000..933dd17e5 --- /dev/null +++ b/apps/angular/52-lazy-load-component/project.json @@ -0,0 +1,81 @@ +{ + "name": "angular-lazy-load-component", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/52-lazy-load-component/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/52-lazy-load-component", + "index": "apps/angular/52-lazy-load-component/src/index.html", + "browser": "apps/angular/52-lazy-load-component/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/52-lazy-load-component/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/52-lazy-load-component/src/favicon.ico", + "apps/angular/52-lazy-load-component/src/assets" + ], + "styles": ["apps/angular/52-lazy-load-component/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-lazy-load-component:build:production" + }, + "development": { + "buildTarget": "angular-lazy-load-component:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-lazy-load-component:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/52-lazy-load-component/src/app/app.component.ts b/apps/angular/52-lazy-load-component/src/app/app.component.ts new file mode 100644 index 000000000..6d8c03d29 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.component.ts @@ -0,0 +1,23 @@ +import { Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` +
+ @if (topLoaded()) { + + } @else { + + + } +
+ `, + standalone: false, +}) +export class AppComponent { + topLoaded = signal(false); +} diff --git a/apps/angular/52-lazy-load-component/src/app/app.module.ts b/apps/angular/52-lazy-load-component/src/app/app.module.ts new file mode 100644 index 000000000..b5d430e67 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { PlaceholderComponent } from './placeholder.component'; +import { TopComponent } from './top.component'; + +@NgModule({ + declarations: [AppComponent, PlaceholderComponent, TopComponent], + imports: [BrowserModule], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts new file mode 100644 index 000000000..cbb2b5fa6 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-placeholder', + template: ` + I'm a placeholder component. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, + standalone: false, +}) +export class PlaceholderComponent {} diff --git a/apps/angular/52-lazy-load-component/src/app/top.component.ts b/apps/angular/52-lazy-load-component/src/app/top.component.ts new file mode 100644 index 000000000..e1ca9012c --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/top.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-top', + template: ` + I am a very heavy, expensive component that should be lazy loaded. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, + standalone: false, +}) +export class TopComponent {} diff --git a/apps/angular/react-in-angular/src/assets/.gitkeep b/apps/angular/52-lazy-load-component/src/assets/.gitkeep similarity index 100% rename from apps/angular/react-in-angular/src/assets/.gitkeep rename to apps/angular/52-lazy-load-component/src/assets/.gitkeep diff --git a/apps/angular/react-in-angular/src/favicon.ico b/apps/angular/52-lazy-load-component/src/favicon.ico similarity index 100% rename from apps/angular/react-in-angular/src/favicon.ico rename to apps/angular/52-lazy-load-component/src/favicon.ico diff --git a/apps/angular/52-lazy-load-component/src/index.html b/apps/angular/52-lazy-load-component/src/index.html new file mode 100644 index 000000000..242ec3e3f --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-lazy-load-component + + + + + + + + diff --git a/apps/angular/52-lazy-load-component/src/main.ts b/apps/angular/52-lazy-load-component/src/main.ts new file mode 100644 index 000000000..8cd87d53b --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic() + .bootstrapModule(AppModule, { + applicationProviders: [provideZoneChangeDetection()], + }) + .catch((err) => console.error(err)); diff --git a/apps/angular/react-in-angular/src/styles.scss b/apps/angular/52-lazy-load-component/src/styles.scss similarity index 100% rename from apps/angular/react-in-angular/src/styles.scss rename to apps/angular/52-lazy-load-component/src/styles.scss diff --git a/apps/angular/52-lazy-load-component/src/test-setup.ts b/apps/angular/52-lazy-load-component/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/signal-input/tailwind.config.js b/apps/angular/52-lazy-load-component/tailwind.config.js similarity index 100% rename from apps/angular/signal-input/tailwind.config.js rename to apps/angular/52-lazy-load-component/tailwind.config.js diff --git a/apps/angular/52-lazy-load-component/tsconfig.app.json b/apps/angular/52-lazy-load-component/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.editor.json b/apps/angular/52-lazy-load-component/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.json b/apps/angular/52-lazy-load-component/tsconfig.json new file mode 100644 index 000000000..ad0529440 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.spec.json b/apps/angular/52-lazy-load-component/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/pipe-intermediate/.eslintrc.json b/apps/angular/55-back-button-navigation/.eslintrc.json similarity index 100% rename from apps/angular/pipe-intermediate/.eslintrc.json rename to apps/angular/55-back-button-navigation/.eslintrc.json diff --git a/apps/angular/55-back-button-navigation/README.md b/apps/angular/55-back-button-navigation/README.md new file mode 100644 index 000000000..2534d270c --- /dev/null +++ b/apps/angular/55-back-button-navigation/README.md @@ -0,0 +1,13 @@ +# Back-Button-Navigation + +> author: ioannis-tsironis + +### Run Application + +```bash +npx nx serve angular-back-button-navigation +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/55-back-button-navigation/). diff --git a/apps/angular/55-back-button-navigation/jest.config.ts b/apps/angular/55-back-button-navigation/jest.config.ts new file mode 100644 index 000000000..f6353cea0 --- /dev/null +++ b/apps/angular/55-back-button-navigation/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'angular-back-button-navigation', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/55-back-button-navigation', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/55-back-button-navigation/project.json b/apps/angular/55-back-button-navigation/project.json new file mode 100644 index 000000000..e6c824729 --- /dev/null +++ b/apps/angular/55-back-button-navigation/project.json @@ -0,0 +1,86 @@ +{ + "name": "angular-back-button-navigation", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/55-back-button-navigation/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/55-back-button-navigation", + "index": "apps/angular/55-back-button-navigation/src/index.html", + "browser": "apps/angular/55-back-button-navigation/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/55-back-button-navigation/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/55-back-button-navigation/public" + } + ], + "styles": [ + "apps/angular/55-back-button-navigation/src/styles.scss", + "node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-back-button-navigation:build:production" + }, + "development": { + "buildTarget": "angular-back-button-navigation:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-back-button-navigation:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/55-back-button-navigation/src/app/app.component.html b/apps/angular/55-back-button-navigation/src/app/app.component.html new file mode 100644 index 000000000..0680b43f9 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/app.component.ts b/apps/angular/55-back-button-navigation/src/app/app.component.ts new file mode 100644 index 000000000..baffdae25 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + templateUrl: './app.component.html', +}) +export class AppComponent {} diff --git a/apps/angular/55-back-button-navigation/src/app/app.config.ts b/apps/angular/55-back-button-navigation/src/app/app.config.ts new file mode 100644 index 000000000..440cdf2c3 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { APP_ROUTES } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(APP_ROUTES), + ], +}; diff --git a/apps/angular/55-back-button-navigation/src/app/app.routes.ts b/apps/angular/55-back-button-navigation/src/app/app.routes.ts new file mode 100644 index 000000000..7deecd57a --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.routes.ts @@ -0,0 +1,24 @@ +import { Routes } from '@angular/router'; +import { HomeComponent } from './home/home.component'; +import { SensitiveActionComponent } from './sensitive-action/sensitive-action.component'; +import { SimpleActionComponent } from './simple-action/simple-action.component'; + +export const APP_ROUTES: Routes = [ + { + path: '', + pathMatch: 'full', + redirectTo: 'home', + }, + { + path: 'home', + component: HomeComponent, + }, + { + path: 'simple-action', + component: SimpleActionComponent, + }, + { + path: 'sensitive-action', + component: SensitiveActionComponent, + }, +]; diff --git a/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html new file mode 100644 index 000000000..ff00ea965 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html @@ -0,0 +1,6 @@ +

Delete file

+Would you like to delete cat.jpeg? + + + + diff --git a/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts new file mode 100644 index 000000000..9a9dd0fef --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogRef, + MatDialogTitle, +} from '@angular/material/dialog'; + +@Component({ + selector: 'app-dialog-dialog', + templateUrl: './dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DialogComponent { + readonly dialogRef = inject(MatDialogRef); +} diff --git a/apps/angular/55-back-button-navigation/src/app/home/home.component.html b/apps/angular/55-back-button-navigation/src/app/home/home.component.html new file mode 100644 index 000000000..cce9e6d4f --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/home/home.component.html @@ -0,0 +1,7 @@ +
+ Go to simple dialog action page + + + + Go to sensitive dialog action page + diff --git a/apps/angular/55-back-button-navigation/src/app/home/home.component.ts b/apps/angular/55-back-button-navigation/src/app/home/home.component.ts new file mode 100644 index 000000000..18c4147b1 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/home/home.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterLink } from '@angular/router'; + +@Component({ + imports: [MatButtonModule, RouterLink], + selector: 'app-home', + templateUrl: './home.component.html', +}) +export class HomeComponent {} diff --git a/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html new file mode 100644 index 000000000..bcb7382e9 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html @@ -0,0 +1,3 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts new file mode 100644 index 000000000..a97282c33 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts @@ -0,0 +1,19 @@ +import { Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialog } from '@angular/material/dialog'; +import { DialogComponent } from '../dialog/dialog.component'; + +@Component({ + imports: [MatButtonModule], + selector: 'app-sensitive-action', + templateUrl: './sensitive-action.component.html', +}) +export class SensitiveActionComponent { + readonly #dialog = inject(MatDialog); + + openDialog(): void { + this.#dialog.open(DialogComponent, { + width: '250px', + }); + } +} diff --git a/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html new file mode 100644 index 000000000..95f63e65e --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html @@ -0,0 +1 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts new file mode 100644 index 000000000..fe97e7368 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts @@ -0,0 +1,19 @@ +import { Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialog } from '@angular/material/dialog'; +import { DialogComponent } from '../dialog/dialog.component'; + +@Component({ + imports: [MatButtonModule], + selector: 'app-simple-action', + templateUrl: './simple-action.component.html', +}) +export class SimpleActionComponent { + readonly #dialog = inject(MatDialog); + + openDialog(): void { + this.#dialog.open(DialogComponent, { + width: '250px', + }); + } +} diff --git a/apps/angular/55-back-button-navigation/src/index.html b/apps/angular/55-back-button-navigation/src/index.html new file mode 100644 index 000000000..4e657d614 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-back-button-navigation + + + + + + + + diff --git a/apps/angular/bug-cd/src/main.ts b/apps/angular/55-back-button-navigation/src/main.ts similarity index 100% rename from apps/angular/bug-cd/src/main.ts rename to apps/angular/55-back-button-navigation/src/main.ts diff --git a/apps/angular/55-back-button-navigation/src/styles.scss b/apps/angular/55-back-button-navigation/src/styles.scss new file mode 100644 index 000000000..acd290007 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/styles.scss @@ -0,0 +1,29 @@ +@use '@angular/material' as mat; + +/* You can add global styles to this file, and also import other style files */ + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@include mat.elevation-classes(); +@include mat.app-background(); + +$theme-primary: mat.m2-define-palette(mat.$m2-indigo-palette); +$theme-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); + +$theme-warn: mat.m2-define-palette(mat.$m2-red-palette); + +$theme: mat.m2-define-light-theme( + ( + color: ( + primary: $theme-primary, + accent: $theme-accent, + warn: $theme-warn, + ), + typography: mat.m2-define-typography-config(), + ) +); + +@include mat.dialog-theme($theme); +@include mat.button-theme($theme); diff --git a/apps/angular/55-back-button-navigation/src/test-setup.ts b/apps/angular/55-back-button-navigation/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/angular/simple-animations/tailwind.config.js b/apps/angular/55-back-button-navigation/tailwind.config.js similarity index 100% rename from apps/angular/simple-animations/tailwind.config.js rename to apps/angular/55-back-button-navigation/tailwind.config.js diff --git a/apps/angular/55-back-button-navigation/tsconfig.app.json b/apps/angular/55-back-button-navigation/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/55-back-button-navigation/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/55-back-button-navigation/tsconfig.editor.json b/apps/angular/55-back-button-navigation/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/55-back-button-navigation/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/55-back-button-navigation/tsconfig.json b/apps/angular/55-back-button-navigation/tsconfig.json new file mode 100644 index 000000000..ad0529440 --- /dev/null +++ b/apps/angular/55-back-button-navigation/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/55-back-button-navigation/tsconfig.spec.json b/apps/angular/55-back-button-navigation/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/angular/55-back-button-navigation/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/angular/react-in-angular/.eslintrc.json b/apps/angular/57-content-projection-default/.eslintrc.json similarity index 100% rename from apps/angular/react-in-angular/.eslintrc.json rename to apps/angular/57-content-projection-default/.eslintrc.json diff --git a/apps/angular/57-content-projection-default/README.md b/apps/angular/57-content-projection-default/README.md new file mode 100644 index 000000000..fc4579558 --- /dev/null +++ b/apps/angular/57-content-projection-default/README.md @@ -0,0 +1,13 @@ +# Content Projection Default + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-default +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/57-content-projection-default/). diff --git a/apps/angular/57-content-projection-default/project.json b/apps/angular/57-content-projection-default/project.json new file mode 100644 index 000000000..0630925f4 --- /dev/null +++ b/apps/angular/57-content-projection-default/project.json @@ -0,0 +1,82 @@ +{ + "name": "angular-content-projection-default", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/57-content-projection-default/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/57-content-projection-default", + "index": "apps/angular/57-content-projection-default/src/index.html", + "browser": "apps/angular/57-content-projection-default/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/57-content-projection-default/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/57-content-projection-default/public" + } + ], + "styles": [ + "apps/angular/57-content-projection-default/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-default:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-default:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-default:build" + } + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-default:build", + "staticFilePath": "dist/apps/angular/57-content-projection-default/browser", + "spa": true + } + } + } +} diff --git a/apps/angular/router-input/src/favicon.ico b/apps/angular/57-content-projection-default/public/favicon.ico similarity index 100% rename from apps/angular/router-input/src/favicon.ico rename to apps/angular/57-content-projection-default/public/favicon.ico diff --git a/apps/angular/57-content-projection-default/src/app/app.component.ts b/apps/angular/57-content-projection-default/src/app/app.component.ts new file mode 100644 index 000000000..b3e370a34 --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/app.component.ts @@ -0,0 +1,16 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CardComponent } from './card.component'; + +@Component({ + imports: [CardComponent], + selector: 'app-root', + template: ` + + + `, + host: { + class: 'p-4 block flex flex-col gap-1', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/57-content-projection-default/src/app/app.config.ts b/apps/angular/57-content-projection-default/src/app/app.config.ts new file mode 100644 index 000000000..034603cfd --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideZoneChangeDetection({ eventCoalescing: true })], +}; diff --git a/apps/angular/57-content-projection-default/src/app/card.component.ts b/apps/angular/57-content-projection-default/src/app/card.component.ts new file mode 100644 index 000000000..851a6619d --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/card.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +@Component({ + selector: 'app-card', + imports: [], + template: ` +
{{ title() }}
+ @if (message()) { +
{{ message() }}
+ } @else { +
Aucun message
+ } + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]', + }, +}) +export class CardComponent { + title = input.required(); + message = input(undefined); +} diff --git a/apps/angular/57-content-projection-default/src/index.html b/apps/angular/57-content-projection-default/src/index.html new file mode 100644 index 000000000..8b3015d4b --- /dev/null +++ b/apps/angular/57-content-projection-default/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-default + + + + + + + + diff --git a/apps/angular/injection-token/src/main.ts b/apps/angular/57-content-projection-default/src/main.ts similarity index 100% rename from apps/angular/injection-token/src/main.ts rename to apps/angular/57-content-projection-default/src/main.ts diff --git a/apps/angular/signal-input/src/styles.scss b/apps/angular/57-content-projection-default/src/styles.scss similarity index 100% rename from apps/angular/signal-input/src/styles.scss rename to apps/angular/57-content-projection-default/src/styles.scss diff --git a/apps/angular/view-transition/tailwind.config.js b/apps/angular/57-content-projection-default/tailwind.config.js similarity index 100% rename from apps/angular/view-transition/tailwind.config.js rename to apps/angular/57-content-projection-default/tailwind.config.js diff --git a/apps/angular/57-content-projection-default/tsconfig.app.json b/apps/angular/57-content-projection-default/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/57-content-projection-default/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/57-content-projection-default/tsconfig.editor.json b/apps/angular/57-content-projection-default/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/57-content-projection-default/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/57-content-projection-default/tsconfig.json b/apps/angular/57-content-projection-default/tsconfig.json new file mode 100644 index 000000000..a82bcf8c3 --- /dev/null +++ b/apps/angular/57-content-projection-default/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/signal-input/.eslintrc.json b/apps/angular/58-content-projection-condition/.eslintrc.json similarity index 100% rename from apps/angular/signal-input/.eslintrc.json rename to apps/angular/58-content-projection-condition/.eslintrc.json diff --git a/apps/angular/58-content-projection-condition/README.md b/apps/angular/58-content-projection-condition/README.md new file mode 100644 index 000000000..755bd8854 --- /dev/null +++ b/apps/angular/58-content-projection-condition/README.md @@ -0,0 +1,13 @@ +# Content Projection Condition + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-condition +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/58-content-projection-condition/). diff --git a/apps/angular/58-content-projection-condition/project.json b/apps/angular/58-content-projection-condition/project.json new file mode 100644 index 000000000..b268984a2 --- /dev/null +++ b/apps/angular/58-content-projection-condition/project.json @@ -0,0 +1,85 @@ +{ + "name": "angular-content-projection-condition", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/58-content-projection-condition/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/58-content-projection-condition", + "index": "apps/angular/58-content-projection-condition/src/index.html", + "browser": "apps/angular/58-content-projection-condition/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/58-content-projection-condition/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/58-content-projection-condition/public" + } + ], + "styles": [ + "apps/angular/58-content-projection-condition/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-condition:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-condition:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-condition:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-condition:build", + "staticFilePath": "dist/apps/angular/58-content-projection-condition/browser", + "spa": true + } + } + } +} diff --git a/apps/angular/signal-input/src/favicon.ico b/apps/angular/58-content-projection-condition/public/favicon.ico similarity index 100% rename from apps/angular/signal-input/src/favicon.ico rename to apps/angular/58-content-projection-condition/public/favicon.ico diff --git a/apps/angular/58-content-projection-condition/src/app/app.component.ts b/apps/angular/58-content-projection-condition/src/app/app.component.ts new file mode 100644 index 000000000..afad56f22 --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/app.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CardComponent } from './card.component'; + +@Component({ + imports: [CardComponent], + selector: 'app-root', + template: ` + +
Card 1
+
Message 1
+
+ +
Card 2
+
Message 2
+
+ `, + host: { + class: 'p-4 block flex flex-col gap-1', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/58-content-projection-condition/src/app/app.config.ts b/apps/angular/58-content-projection-condition/src/app/app.config.ts new file mode 100644 index 000000000..034603cfd --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideZoneChangeDetection({ eventCoalescing: true })], +}; diff --git a/apps/angular/58-content-projection-condition/src/app/card.component.ts b/apps/angular/58-content-projection-condition/src/app/card.component.ts new file mode 100644 index 000000000..46925977c --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/card.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +@Component({ + selector: 'app-card', + template: ` + @if (small()) { + + + } @else { +
+
+ +
+ +
+ } + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]', + }, +}) +export class CardComponent { + small = input(false); +} diff --git a/apps/angular/58-content-projection-condition/src/index.html b/apps/angular/58-content-projection-condition/src/index.html new file mode 100644 index 000000000..f1768ec71 --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-condition + + + + + + + + diff --git a/apps/angular/interop-rxjs-signal/src/main.ts b/apps/angular/58-content-projection-condition/src/main.ts similarity index 100% rename from apps/angular/interop-rxjs-signal/src/main.ts rename to apps/angular/58-content-projection-condition/src/main.ts diff --git a/apps/angular/simple-animations/src/styles.scss b/apps/angular/58-content-projection-condition/src/styles.scss similarity index 100% rename from apps/angular/simple-animations/src/styles.scss rename to apps/angular/58-content-projection-condition/src/styles.scss diff --git a/apps/forms/control-value-accessor/tailwind.config.js b/apps/angular/58-content-projection-condition/tailwind.config.js similarity index 100% rename from apps/forms/control-value-accessor/tailwind.config.js rename to apps/angular/58-content-projection-condition/tailwind.config.js diff --git a/apps/angular/58-content-projection-condition/tsconfig.app.json b/apps/angular/58-content-projection-condition/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/58-content-projection-condition/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/58-content-projection-condition/tsconfig.editor.json b/apps/angular/58-content-projection-condition/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/58-content-projection-condition/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/58-content-projection-condition/tsconfig.json b/apps/angular/58-content-projection-condition/tsconfig.json new file mode 100644 index 000000000..a82bcf8c3 --- /dev/null +++ b/apps/angular/58-content-projection-condition/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/59-content-projection-defer/.eslintrc.json b/apps/angular/59-content-projection-defer/.eslintrc.json new file mode 100644 index 000000000..995177b5b --- /dev/null +++ b/apps/angular/59-content-projection-defer/.eslintrc.json @@ -0,0 +1,37 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/component-class-suffix": "off", + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/angular/59-content-projection-defer/README.md b/apps/angular/59-content-projection-defer/README.md new file mode 100644 index 000000000..f726842d1 --- /dev/null +++ b/apps/angular/59-content-projection-defer/README.md @@ -0,0 +1,13 @@ +# content-projection-defer + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-defer +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/59-content-projection-defer/). diff --git a/apps/angular/59-content-projection-defer/project.json b/apps/angular/59-content-projection-defer/project.json new file mode 100644 index 000000000..efd270b03 --- /dev/null +++ b/apps/angular/59-content-projection-defer/project.json @@ -0,0 +1,83 @@ +{ + "name": "angular-content-projection-defer", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/59-content-projection-defer/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/59-content-projection-defer", + "index": "apps/angular/59-content-projection-defer/src/index.html", + "browser": "apps/angular/59-content-projection-defer/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/59-content-projection-defer/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/59-content-projection-defer/public" + } + ], + "styles": ["apps/angular/59-content-projection-defer/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-defer:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-defer:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-defer:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-defer:build", + "staticFilePath": "dist/apps/angular/59-content-projection-defer/browser", + "spa": true + } + } + } +} diff --git a/apps/angular/simple-animations/src/favicon.ico b/apps/angular/59-content-projection-defer/public/favicon.ico similarity index 100% rename from apps/angular/simple-animations/src/favicon.ico rename to apps/angular/59-content-projection-defer/public/favicon.ico diff --git a/apps/angular/59-content-projection-defer/src/app/app.component.ts b/apps/angular/59-content-projection-defer/src/app/app.component.ts new file mode 100644 index 000000000..ae40bc880 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.component.ts @@ -0,0 +1,23 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + template: ` +
+ + +
+ + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'flex flex-col gap-2 ', + }, +}) +export class AppComponent {} diff --git a/apps/angular/59-content-projection-defer/src/app/app.config.ts b/apps/angular/59-content-projection-defer/src/app/app.config.ts new file mode 100644 index 000000000..faf4d099a --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.config.ts @@ -0,0 +1,12 @@ +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { appRoutes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(appRoutes), + provideHttpClient(), + ], +}; diff --git a/apps/angular/59-content-projection-defer/src/app/app.routes.ts b/apps/angular/59-content-projection-defer/src/app/app.routes.ts new file mode 100644 index 000000000..3ca1b67cc --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.routes.ts @@ -0,0 +1,13 @@ +import { Route } from '@angular/router'; + +export const appRoutes: Route[] = [ + { + path: 'page-1', + loadComponent: () => import('./page-1').then((m) => m.Page1), + }, + { + path: 'page-2', + loadComponent: () => import('./page-2').then((m) => m.Page2), + }, + { path: '**', redirectTo: 'page-1' }, +]; diff --git a/apps/angular/59-content-projection-defer/src/app/expandable-card.ts b/apps/angular/59-content-projection-defer/src/app/expandable-card.ts new file mode 100644 index 000000000..8f446ed80 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/expandable-card.ts @@ -0,0 +1,54 @@ +import { ChangeDetectionStrategy, Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-expandable-card', + template: ` + + +
+ +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'flex flex-col gap-2 ', + }, +}) +export class ExpandableCard { + public isExpanded = signal(false); +} diff --git a/apps/angular/59-content-projection-defer/src/app/page-1.ts b/apps/angular/59-content-projection-defer/src/app/page-1.ts new file mode 100644 index 000000000..868d76959 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/page-1.ts @@ -0,0 +1,10 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-page-1', + template: ` + page1 + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class Page1 {} diff --git a/apps/angular/59-content-projection-defer/src/app/page-2.ts b/apps/angular/59-content-projection-defer/src/app/page-2.ts new file mode 100644 index 000000000..5665466d8 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/page-2.ts @@ -0,0 +1,43 @@ +import { httpResource } from '@angular/common/http'; +import { + ChangeDetectionStrategy, + Component, + ResourceStatus, +} from '@angular/core'; +import { ExpandableCard } from './expandable-card'; + +interface Post { + id: number; + title: string; + body: string; + userId: number; +} + +@Component({ + selector: 'app-page-2', + template: ` + page2 + +
Load Post
+
+ @if (postResource.isLoading()) { + Loading... + } @else if (postResource.status() === ResourceStatus.Error) { + Error... + } @else { + @for (post of postResource.value(); track post.id) { +
{{ post.title }}
+ } + } +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ExpandableCard], +}) +export class Page2 { + public postResource = httpResource( + 'https://jsonplaceholder.typicode.com/posts', + ); + protected readonly ResourceStatus = ResourceStatus; +} diff --git a/apps/angular/59-content-projection-defer/src/index.html b/apps/angular/59-content-projection-defer/src/index.html new file mode 100644 index 000000000..79f435fa6 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-defer + + + + + + + + diff --git a/apps/angular/react-in-angular/src/main.ts b/apps/angular/59-content-projection-defer/src/main.ts similarity index 100% rename from apps/angular/react-in-angular/src/main.ts rename to apps/angular/59-content-projection-defer/src/main.ts diff --git a/apps/forms/control-value-accessor/src/styles.scss b/apps/angular/59-content-projection-defer/src/styles.scss similarity index 100% rename from apps/forms/control-value-accessor/src/styles.scss rename to apps/angular/59-content-projection-defer/src/styles.scss diff --git a/apps/nx/static-dynamic-import/tailwind.config.js b/apps/angular/59-content-projection-defer/tailwind.config.js similarity index 100% rename from apps/nx/static-dynamic-import/tailwind.config.js rename to apps/angular/59-content-projection-defer/tailwind.config.js diff --git a/apps/angular/59-content-projection-defer/tsconfig.app.json b/apps/angular/59-content-projection-defer/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/angular/59-content-projection-defer/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/59-content-projection-defer/tsconfig.editor.json b/apps/angular/59-content-projection-defer/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/59-content-projection-defer/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/59-content-projection-defer/tsconfig.json b/apps/angular/59-content-projection-defer/tsconfig.json new file mode 100644 index 000000000..a82bcf8c3 --- /dev/null +++ b/apps/angular/59-content-projection-defer/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/simple-animations/.eslintrc.json b/apps/angular/6-structural-directive/.eslintrc.json similarity index 100% rename from apps/angular/simple-animations/.eslintrc.json rename to apps/angular/6-structural-directive/.eslintrc.json diff --git a/apps/angular/6-structural-directive/README.md b/apps/angular/6-structural-directive/README.md new file mode 100644 index 000000000..775b40981 --- /dev/null +++ b/apps/angular/6-structural-directive/README.md @@ -0,0 +1,13 @@ +# Structural Directive + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-structural-directive +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/6-permissions/). diff --git a/apps/angular/6-structural-directive/project.json b/apps/angular/6-structural-directive/project.json new file mode 100644 index 000000000..399418f90 --- /dev/null +++ b/apps/angular/6-structural-directive/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-structural-directive", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/6-structural-directive/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/6-structural-directive", + "index": "apps/angular/6-structural-directive/src/index.html", + "main": "apps/angular/6-structural-directive/src/main.ts", + "polyfills": "apps/angular/6-structural-directive/src/polyfills.ts", + "tsConfig": "apps/angular/6-structural-directive/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/6-structural-directive/src/favicon.ico", + "apps/angular/6-structural-directive/src/assets" + ], + "styles": ["apps/angular/6-structural-directive/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-structural-directive:build:production" + }, + "development": { + "buildTarget": "angular-structural-directive:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-structural-directive:build" + } + } + } +} diff --git a/apps/angular/6-structural-directive/src/app/app.component.ts b/apps/angular/6-structural-directive/src/app/app.component.ts new file mode 100644 index 000000000..1fcb0c548 --- /dev/null +++ b/apps/angular/6-structural-directive/src/app/app.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/permissions/src/app/app.config.ts b/apps/angular/6-structural-directive/src/app/app.config.ts similarity index 100% rename from apps/angular/permissions/src/app/app.config.ts rename to apps/angular/6-structural-directive/src/app/app.config.ts diff --git a/apps/angular/permissions/src/app/button.component.ts b/apps/angular/6-structural-directive/src/app/button.component.ts similarity index 88% rename from apps/angular/permissions/src/app/button.component.ts rename to apps/angular/6-structural-directive/src/app/button.component.ts index b1d59e8cc..5d1323605 100644 --- a/apps/angular/permissions/src/app/button.component.ts +++ b/apps/angular/6-structural-directive/src/app/button.component.ts @@ -2,10 +2,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ - standalone: true, selector: 'button[app-button]', template: ` - + `, host: { class: 'border border-blue-700 bg-blue-400 p-2 rounded-sm text-white', diff --git a/apps/angular/permissions/src/app/dashboard/admin.component.ts b/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts similarity index 95% rename from apps/angular/permissions/src/app/dashboard/admin.component.ts rename to apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts index 72e4b3bef..26bb23284 100644 --- a/apps/angular/permissions/src/app/dashboard/admin.component.ts +++ b/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts @@ -4,7 +4,6 @@ import { ButtonComponent } from '../button.component'; @Component({ selector: 'app-dashboard', - standalone: true, imports: [RouterLink, ButtonComponent], template: `

dashboard for Admin works!

diff --git a/apps/angular/6-structural-directive/src/app/dashboard/manager.component.ts b/apps/angular/6-structural-directive/src/app/dashboard/manager.component.ts new file mode 100644 index 000000000..60ea7695b --- /dev/null +++ b/apps/angular/6-structural-directive/src/app/dashboard/manager.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + imports: [], + template: ` +

dashboard for Manager works!

+ + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ManagerDashboardComponent {} diff --git a/apps/angular/6-structural-directive/src/app/information.component.ts b/apps/angular/6-structural-directive/src/app/information.component.ts new file mode 100644 index 000000000..ecf937efc --- /dev/null +++ b/apps/angular/6-structural-directive/src/app/information.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { UserStore } from './user.store'; + +@Component({ + selector: 'app-information', + template: ` +

Information Panel

+ +
visible only for super admin
+
visible if manager
+
visible if manager and/or reader
+
visible if manager and/or writer
+
visible if client
+
visible for everyone
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class InformationComponent { + private readonly userStore = inject(UserStore); + + user$ = this.userStore.user$; +} diff --git a/apps/angular/permissions/src/app/login.component.ts b/apps/angular/6-structural-directive/src/app/login.component.ts similarity index 90% rename from apps/angular/permissions/src/app/login.component.ts rename to apps/angular/6-structural-directive/src/app/login.component.ts index cd36d9603..f38e5e5ca 100644 --- a/apps/angular/permissions/src/app/login.component.ts +++ b/apps/angular/6-structural-directive/src/app/login.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { RouterLink } from '@angular/router'; import { ButtonComponent } from './button.component'; import { InformationComponent } from './information.component'; @@ -14,7 +14,6 @@ import { import { UserStore } from './user.store'; @Component({ - standalone: true, imports: [InformationComponent, RouterLink, ButtonComponent], selector: 'app-login', template: ` @@ -29,7 +28,7 @@ import { UserStore } from './user.store'; - + +

Page A (Admin)

+ `, + + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterLink], +}) +export class AdminPage {} diff --git a/apps/angular/60-async-redirect/src/app/app.config.ts b/apps/angular/60-async-redirect/src/app/app.config.ts new file mode 100644 index 000000000..76220a9c0 --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/app.config.ts @@ -0,0 +1,16 @@ +import { + ApplicationConfig, + provideBrowserGlobalErrorListeners, + provideZoneChangeDetection, +} from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(routes), + ], +}; diff --git a/apps/angular/60-async-redirect/src/app/app.ts b/apps/angular/60-async-redirect/src/app/app.ts new file mode 100644 index 000000000..aa29b8e76 --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/app.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterOutlet], +}) +export class App {} diff --git a/apps/angular/60-async-redirect/src/app/dashboard.ts b/apps/angular/60-async-redirect/src/app/dashboard.ts new file mode 100644 index 000000000..377c5e81d --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/dashboard.ts @@ -0,0 +1,34 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { Router, RouterLink, RouterOutlet } from '@angular/router'; +import { UserProfileService } from './user-profile.service'; + +@Component({ + selector: 'app-dashboard', + template: ` +
+ + +
+ + `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterOutlet, RouterLink], +}) +export class Dashboard { + private router = inject(Router); + private userProfile = inject(UserProfileService); + + navigate() { + this.userProfile.getProfile().subscribe((profile) => { + void this.router.navigate(['/', profile]); + }); + } +} diff --git a/apps/angular/60-async-redirect/src/app/profile-page.ts b/apps/angular/60-async-redirect/src/app/profile-page.ts new file mode 100644 index 000000000..a92779d07 --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/profile-page.ts @@ -0,0 +1,45 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + signal, +} from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { UserProfileService } from './user-profile.service'; + +@Component({ + selector: 'app-profile-page', + template: ` + +
+ + +
+
+ Current profile: {{ selectedProfile() }} +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterLink], +}) +export class ProfilePage { + private userProfile = inject(UserProfileService); + selectedProfile = signal<'admin' | 'user'>('admin'); + + chooseProfile(profile: 'admin' | 'user') { + this.userProfile.setProfile(profile); + this.selectedProfile.set(profile); + } +} diff --git a/apps/angular/60-async-redirect/src/app/routes.ts b/apps/angular/60-async-redirect/src/app/routes.ts new file mode 100644 index 000000000..4a0f11835 --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/routes.ts @@ -0,0 +1,20 @@ +import { Routes } from '@angular/router'; +import { AdminPage } from './admin-page'; +import { App } from './app'; +import { Dashboard } from './dashboard'; +import { ProfilePage } from './profile-page'; +import { UserPage } from './user-page'; + +export const routes: Routes = [ + { + path: '', + component: App, + children: [ + { path: '', pathMatch: 'full', component: Dashboard }, + { path: 'profile', component: ProfilePage }, + { path: 'admin', component: AdminPage }, + { path: 'user', component: UserPage }, + ], + }, + { path: '**', redirectTo: '', pathMatch: 'full' }, +]; diff --git a/apps/angular/60-async-redirect/src/app/user-page.ts b/apps/angular/60-async-redirect/src/app/user-page.ts new file mode 100644 index 000000000..fdb159bac --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/user-page.ts @@ -0,0 +1,17 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-page-b', + template: ` + +

User page

+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [RouterLink], +}) +export class UserPage {} diff --git a/apps/angular/60-async-redirect/src/app/user-profile.service.ts b/apps/angular/60-async-redirect/src/app/user-profile.service.ts new file mode 100644 index 000000000..b13f611e7 --- /dev/null +++ b/apps/angular/60-async-redirect/src/app/user-profile.service.ts @@ -0,0 +1,16 @@ +import { Injectable, signal } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { delay } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class UserProfileService { + private profile = signal<'admin' | 'user'>('admin'); + + setProfile(profile: 'admin' | 'user') { + this.profile.set(profile); + } + + getProfile(): Observable<'admin' | 'user'> { + return of(this.profile()).pipe(delay(300)); + } +} diff --git a/apps/angular/60-async-redirect/src/index.html b/apps/angular/60-async-redirect/src/index.html new file mode 100644 index 000000000..e81550c8d --- /dev/null +++ b/apps/angular/60-async-redirect/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-async-redirect + + + + + + + + diff --git a/apps/angular/60-async-redirect/src/main.ts b/apps/angular/60-async-redirect/src/main.ts new file mode 100644 index 000000000..2108cd95d --- /dev/null +++ b/apps/angular/60-async-redirect/src/main.ts @@ -0,0 +1,5 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { App } from './app/app'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(App, appConfig).catch((err) => console.error(err)); diff --git a/apps/performance/christmas-web-worker/src/styles.scss b/apps/angular/60-async-redirect/src/styles.scss similarity index 100% rename from apps/performance/christmas-web-worker/src/styles.scss rename to apps/angular/60-async-redirect/src/styles.scss diff --git a/apps/performance/default-onpush/tailwind.config.js b/apps/angular/60-async-redirect/tailwind.config.js similarity index 100% rename from apps/performance/default-onpush/tailwind.config.js rename to apps/angular/60-async-redirect/tailwind.config.js diff --git a/apps/angular/60-async-redirect/tsconfig.app.json b/apps/angular/60-async-redirect/tsconfig.app.json new file mode 100644 index 000000000..5d5af52c7 --- /dev/null +++ b/apps/angular/60-async-redirect/tsconfig.app.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": [ + "jest.config.ts", + "src/test-setup.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts" + ] +} diff --git a/apps/angular/60-async-redirect/tsconfig.json b/apps/angular/60-async-redirect/tsconfig.json new file mode 100644 index 000000000..7923f5435 --- /dev/null +++ b/apps/angular/60-async-redirect/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "target": "es2022", + "moduleResolution": "bundler", + "isolatedModules": true, + "emitDecoratorMetadata": false, + "module": "preserve", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, + "strictTemplates": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/apps/ngrx/effect-selector/.eslintrc.json b/apps/angular/8-pure-pipe/.eslintrc.json similarity index 100% rename from apps/ngrx/effect-selector/.eslintrc.json rename to apps/angular/8-pure-pipe/.eslintrc.json diff --git a/apps/angular/8-pure-pipe/README.md b/apps/angular/8-pure-pipe/README.md new file mode 100644 index 000000000..a65a33f85 --- /dev/null +++ b/apps/angular/8-pure-pipe/README.md @@ -0,0 +1,13 @@ +# Pure Pipe + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-pure-pipe +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/8-pipe-pure/). diff --git a/apps/angular/8-pure-pipe/project.json b/apps/angular/8-pure-pipe/project.json new file mode 100644 index 000000000..26f507b63 --- /dev/null +++ b/apps/angular/8-pure-pipe/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-pure-pipe", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/8-pure-pipe/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/8-pure-pipe", + "index": "apps/angular/8-pure-pipe/src/index.html", + "main": "apps/angular/8-pure-pipe/src/main.ts", + "polyfills": "apps/angular/8-pure-pipe/src/polyfills.ts", + "tsConfig": "apps/angular/8-pure-pipe/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/8-pure-pipe/src/favicon.ico", + "apps/angular/8-pure-pipe/src/assets" + ], + "styles": ["apps/angular/8-pure-pipe/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-pure-pipe:build:production" + }, + "development": { + "buildTarget": "angular-pure-pipe:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-pure-pipe:build" + } + } + } +} diff --git a/apps/angular/8-pure-pipe/src/app/app.component.ts b/apps/angular/8-pure-pipe/src/app/app.component.ts new file mode 100644 index 000000000..930fe1313 --- /dev/null +++ b/apps/angular/8-pure-pipe/src/app/app.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` + @for (person of persons; track person) { + {{ heavyComputation(person, $index) }} + } + `, +}) +export class AppComponent { + persons = ['toto', 'jack']; + + heavyComputation(name: string, index: number) { + // very heavy computation + return `${name} - ${index}`; + } +} diff --git a/apps/angular/signal-input/src/assets/.gitkeep b/apps/angular/8-pure-pipe/src/assets/.gitkeep similarity index 100% rename from apps/angular/signal-input/src/assets/.gitkeep rename to apps/angular/8-pure-pipe/src/assets/.gitkeep diff --git a/apps/forms/control-value-accessor/src/favicon.ico b/apps/angular/8-pure-pipe/src/favicon.ico similarity index 100% rename from apps/forms/control-value-accessor/src/favicon.ico rename to apps/angular/8-pure-pipe/src/favicon.ico diff --git a/apps/angular/8-pure-pipe/src/index.html b/apps/angular/8-pure-pipe/src/index.html new file mode 100644 index 000000000..c8ee70b97 --- /dev/null +++ b/apps/angular/8-pure-pipe/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-pure-pipe + + + + + + + + diff --git a/apps/angular/8-pure-pipe/src/main.ts b/apps/angular/8-pure-pipe/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/8-pure-pipe/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-hard/src/polyfills.ts b/apps/angular/8-pure-pipe/src/polyfills.ts similarity index 100% rename from apps/angular/pipe-hard/src/polyfills.ts rename to apps/angular/8-pure-pipe/src/polyfills.ts diff --git a/apps/angular/pipe-intermediate/src/styles.scss b/apps/angular/8-pure-pipe/src/styles.scss similarity index 100% rename from apps/angular/pipe-intermediate/src/styles.scss rename to apps/angular/8-pure-pipe/src/styles.scss diff --git a/apps/angular/8-pure-pipe/tsconfig.app.json b/apps/angular/8-pure-pipe/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/8-pure-pipe/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/pipe-easy/tsconfig.editor.json b/apps/angular/8-pure-pipe/tsconfig.editor.json similarity index 100% rename from apps/angular/pipe-easy/tsconfig.editor.json rename to apps/angular/8-pure-pipe/tsconfig.editor.json diff --git a/apps/angular/8-pure-pipe/tsconfig.json b/apps/angular/8-pure-pipe/tsconfig.json new file mode 100644 index 000000000..f512037ca --- /dev/null +++ b/apps/angular/8-pure-pipe/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/ngrx/notification/.eslintrc.json b/apps/angular/9-wrap-function-pipe/.eslintrc.json similarity index 100% rename from apps/ngrx/notification/.eslintrc.json rename to apps/angular/9-wrap-function-pipe/.eslintrc.json diff --git a/apps/angular/9-wrap-function-pipe/README.md b/apps/angular/9-wrap-function-pipe/README.md new file mode 100644 index 000000000..1491e7dda --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/README.md @@ -0,0 +1,13 @@ +# Wrap Function Pipe + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-wrap-function-pipe +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/9-pipe-wrapFn/). diff --git a/apps/angular/9-wrap-function-pipe/project.json b/apps/angular/9-wrap-function-pipe/project.json new file mode 100644 index 000000000..ce32ac0c1 --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-wrap-function-pipe", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/angular/9-wrap-function-pipe/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/9-wrap-function-pipe", + "index": "apps/angular/9-wrap-function-pipe/src/index.html", + "main": "apps/angular/9-wrap-function-pipe/src/main.ts", + "polyfills": "apps/angular/9-wrap-function-pipe/src/polyfills.ts", + "tsConfig": "apps/angular/9-wrap-function-pipe/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/9-wrap-function-pipe/src/favicon.ico", + "apps/angular/9-wrap-function-pipe/src/assets" + ], + "styles": ["apps/angular/9-wrap-function-pipe/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-wrap-function-pipe:build:production" + }, + "development": { + "buildTarget": "angular-wrap-function-pipe:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-wrap-function-pipe:build" + } + } + } +} diff --git a/apps/angular/9-wrap-function-pipe/src/app/app.component.ts b/apps/angular/9-wrap-function-pipe/src/app/app.component.ts new file mode 100644 index 000000000..af8b6ff73 --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/src/app/app.component.ts @@ -0,0 +1,31 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` + @for (person of persons; track person.name) { + {{ showName(person.name, $index) }} + {{ isAllowed(person.age, $first) }} + } + `, +}) +export class AppComponent { + persons = [ + { name: 'Toto', age: 10 }, + { name: 'Jack', age: 15 }, + { name: 'John', age: 30 }, + ]; + + showName(name: string, index: number) { + // very heavy computation + return `${name} - ${index}`; + } + + isAllowed(age: number, isFirst: boolean) { + if (isFirst) { + return 'always allowed'; + } else { + return age > 25 ? 'allowed' : 'declined'; + } + } +} diff --git a/apps/angular/simple-animations/src/assets/.gitkeep b/apps/angular/9-wrap-function-pipe/src/assets/.gitkeep similarity index 100% rename from apps/angular/simple-animations/src/assets/.gitkeep rename to apps/angular/9-wrap-function-pipe/src/assets/.gitkeep diff --git a/apps/ngrx/effect-selector/src/favicon.ico b/apps/angular/9-wrap-function-pipe/src/favicon.ico similarity index 100% rename from apps/ngrx/effect-selector/src/favicon.ico rename to apps/angular/9-wrap-function-pipe/src/favicon.ico diff --git a/apps/angular/9-wrap-function-pipe/src/index.html b/apps/angular/9-wrap-function-pipe/src/index.html new file mode 100644 index 000000000..bc8a0ddbd --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-wrap-function-pipe + + + + + + + + diff --git a/apps/angular/9-wrap-function-pipe/src/main.ts b/apps/angular/9-wrap-function-pipe/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-intermediate/src/polyfills.ts b/apps/angular/9-wrap-function-pipe/src/polyfills.ts similarity index 100% rename from apps/angular/pipe-intermediate/src/polyfills.ts rename to apps/angular/9-wrap-function-pipe/src/polyfills.ts diff --git a/apps/angular/router-input/src/styles.scss b/apps/angular/9-wrap-function-pipe/src/styles.scss similarity index 100% rename from apps/angular/router-input/src/styles.scss rename to apps/angular/9-wrap-function-pipe/src/styles.scss diff --git a/apps/angular/9-wrap-function-pipe/tsconfig.app.json b/apps/angular/9-wrap-function-pipe/tsconfig.app.json new file mode 100644 index 000000000..2a1ca1b8d --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "target": "ES2022", + "useDefineForClassFields": false, + "moduleResolution": "bundler" + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/pipe-hard/tsconfig.editor.json b/apps/angular/9-wrap-function-pipe/tsconfig.editor.json similarity index 100% rename from apps/angular/pipe-hard/tsconfig.editor.json rename to apps/angular/9-wrap-function-pipe/tsconfig.editor.json diff --git a/apps/angular/9-wrap-function-pipe/tsconfig.json b/apps/angular/9-wrap-function-pipe/tsconfig.json new file mode 100644 index 000000000..f512037ca --- /dev/null +++ b/apps/angular/9-wrap-function-pipe/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/anchor-scrolling/README.md b/apps/angular/anchor-scrolling/README.md deleted file mode 100644 index a159fd8b7..000000000 --- a/apps/angular/anchor-scrolling/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Anchor Navigation - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-anchor-scrolling -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/21-achor-scrolling/). diff --git a/apps/angular/anchor-scrolling/jest.config.ts b/apps/angular/anchor-scrolling/jest.config.ts deleted file mode 100644 index 6915111a0..000000000 --- a/apps/angular/anchor-scrolling/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-anchor-scrolling', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/anchor-scrolling', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/anchor-scrolling/project.json b/apps/angular/anchor-scrolling/project.json deleted file mode 100644 index 8db932f32..000000000 --- a/apps/angular/anchor-scrolling/project.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "angular-anchor-scrolling", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/anchor-scrolling/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/anchor-scrolling", - "index": "apps/angular/anchor-scrolling/src/index.html", - "main": "apps/angular/anchor-scrolling/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/anchor-scrolling/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/anchor-scrolling/src/favicon.ico", - "apps/angular/anchor-scrolling/src/assets" - ], - "styles": ["apps/angular/anchor-scrolling/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-anchor-scrolling:build:production" - }, - "development": { - "buildTarget": "angular-anchor-scrolling:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-anchor-scrolling:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/anchor-scrolling/jest.config.ts" - } - } - }, - "tags": [] -} diff --git a/apps/angular/anchor-scrolling/src/app/app.component.ts b/apps/angular/anchor-scrolling/src/app/app.component.ts deleted file mode 100644 index 3fb7c5df0..000000000 --- a/apps/angular/anchor-scrolling/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent {} diff --git a/apps/angular/anchor-scrolling/src/app/foo.component.ts b/apps/angular/anchor-scrolling/src/app/foo.component.ts deleted file mode 100644 index 87f9b59d9..000000000 --- a/apps/angular/anchor-scrolling/src/app/foo.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; -import { NavButtonComponent } from './nav-button.component'; - -@Component({ - standalone: true, - imports: [NavButtonComponent], - selector: 'app-foo', - template: ` - Welcome to foo page - Home Page -
section 1
-
section 2
- `, -}) -export class FooComponent {} diff --git a/apps/angular/anchor-scrolling/src/app/home.component.ts b/apps/angular/anchor-scrolling/src/app/home.component.ts deleted file mode 100644 index 0f24ff6e7..000000000 --- a/apps/angular/anchor-scrolling/src/app/home.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component } from '@angular/core'; -import { NavButtonComponent } from './nav-button.component'; - -@Component({ - standalone: true, - imports: [NavButtonComponent], - selector: 'app-home', - template: ` - Foo Page -
- Empty - Scroll Bottom -
-
- I want to scroll each - Scroll Top -
- `, -}) -export class HomeComponent {} diff --git a/apps/angular/anchor-scrolling/src/app/nav-button.component.ts b/apps/angular/anchor-scrolling/src/app/nav-button.component.ts deleted file mode 100644 index 9e3b6d42f..000000000 --- a/apps/angular/anchor-scrolling/src/app/nav-button.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { Component, Input } from '@angular/core'; -@Component({ - selector: 'nav-button', - standalone: true, - template: ` - - - - `, - host: { - class: 'block w-fit border border-red-500 rounded-md p-4 m-2', - }, -}) -export class NavButtonComponent { - @Input() href = ''; -} diff --git a/apps/angular/anchor-scrolling/src/index.html b/apps/angular/anchor-scrolling/src/index.html deleted file mode 100644 index 7a2a4b377..000000000 --- a/apps/angular/anchor-scrolling/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - AnchorScrolling - - - - - - - - diff --git a/apps/angular/anchor-scrolling/src/main.ts b/apps/angular/anchor-scrolling/src/main.ts deleted file mode 100644 index 7961924bf..000000000 --- a/apps/angular/anchor-scrolling/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/angular/anchor-scrolling/src/test-setup.ts b/apps/angular/anchor-scrolling/src/test-setup.ts deleted file mode 100644 index 1100b3e8a..000000000 --- a/apps/angular/anchor-scrolling/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/anchor-scrolling/tsconfig.app.json b/apps/angular/anchor-scrolling/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/anchor-scrolling/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/anchor-scrolling/tsconfig.json b/apps/angular/anchor-scrolling/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/angular/anchor-scrolling/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/anchor-scrolling/tsconfig.spec.json b/apps/angular/anchor-scrolling/tsconfig.spec.json deleted file mode 100644 index ca14cc622..000000000 --- a/apps/angular/anchor-scrolling/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/bug-cd/README.md b/apps/angular/bug-cd/README.md deleted file mode 100644 index cb42e778c..000000000 --- a/apps/angular/bug-cd/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Change Detection Bug - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-bug-cd -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/32-bug-cd/). diff --git a/apps/angular/bug-cd/jest.config.ts b/apps/angular/bug-cd/jest.config.ts deleted file mode 100644 index 1f24a7ce5..000000000 --- a/apps/angular/bug-cd/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-bug-cd', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/bug-cd', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/bug-cd/project.json b/apps/angular/bug-cd/project.json deleted file mode 100644 index 1ba6cdf5a..000000000 --- a/apps/angular/bug-cd/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "angular-bug-cd", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/bug-cd/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/bug-cd", - "index": "apps/angular/bug-cd/src/index.html", - "main": "apps/angular/bug-cd/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/bug-cd/tsconfig.app.json", - "assets": [ - "apps/angular/bug-cd/src/favicon.ico", - "apps/angular/bug-cd/src/assets" - ], - "styles": ["apps/angular/bug-cd/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-bug-cd:build:production" - }, - "development": { - "buildTarget": "angular-bug-cd:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-bug-cd:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/bug-cd/jest.config.ts" - } - } - } -} diff --git a/apps/angular/bug-cd/src/app/app.component.ts b/apps/angular/bug-cd/src/app/app.component.ts deleted file mode 100644 index 046492f9b..000000000 --- a/apps/angular/bug-cd/src/app/app.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet], - selector: 'app-root', - template: ` -

My Application

-
- -
- -
-
- `, - host: { - class: 'flex flex-col gap-2', - }, -}) -export class AppComponent {} diff --git a/apps/angular/bug-cd/src/app/foo.component.ts b/apps/angular/bug-cd/src/app/foo.component.ts deleted file mode 100644 index a5b1207b1..000000000 --- a/apps/angular/bug-cd/src/app/foo.component.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Component } from '@angular/core'; -@Component({ - selector: 'app-foo', - standalone: true, - template: ` - Foo Component - `, -}) -export class FooComponent {} diff --git a/apps/angular/bug-cd/src/app/main-navigation.component.ts b/apps/angular/bug-cd/src/app/main-navigation.component.ts deleted file mode 100644 index c8a6f6d22..000000000 --- a/apps/angular/bug-cd/src/app/main-navigation.component.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { AsyncPipe, NgFor, NgIf } from '@angular/common'; -import { Component, Input, inject } from '@angular/core'; -import { RouterLink, RouterLinkActive } from '@angular/router'; -import { FakeServiceService } from './fake.service'; - -interface MenuItem { - path: string; - name: string; -} - -@Component({ - selector: 'app-nav', - standalone: true, - imports: [RouterLink, RouterLinkActive, NgFor], - template: ` - - - {{ menu.name }} - - - `, - styles: [ - ` - a.isSelected { - @apply bg-gray-600 text-white; - } - `, - ], - host: { - class: 'flex flex-col p-2 gap-2', - }, -}) -export class NavigationComponent { - @Input() menus!: MenuItem[]; -} - -@Component({ - standalone: true, - imports: [NavigationComponent, NgIf, AsyncPipe], - template: ` - - - - - - - - - - `, - host: {}, -}) -export class MainNavigationComponent { - private fakeBackend = inject(FakeServiceService); - - readonly info$ = this.fakeBackend.getInfoFromBackend(); - - getMenu(prop: string) { - return [ - { path: '/foo', name: `Foo ${prop}` }, - { path: '/bar', name: `Bar ${prop}` }, - ]; - } -} diff --git a/apps/angular/bug-cd/src/index.html b/apps/angular/bug-cd/src/index.html deleted file mode 100644 index ab925a75c..000000000 --- a/apps/angular/bug-cd/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - test - - - - - - - - diff --git a/apps/angular/bug-cd/src/test-setup.ts b/apps/angular/bug-cd/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/bug-cd/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/bug-cd/tsconfig.app.json b/apps/angular/bug-cd/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/bug-cd/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/bug-cd/tsconfig.json b/apps/angular/bug-cd/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/angular/bug-cd/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/bug-cd/tsconfig.spec.json b/apps/angular/bug-cd/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/angular/bug-cd/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/context-outlet-type/README.md b/apps/angular/context-outlet-type/README.md deleted file mode 100644 index d195baa04..000000000 --- a/apps/angular/context-outlet-type/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Typed ContextOutlet - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-context-outlet-type -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/4-context-outlet-typed/). diff --git a/apps/angular/context-outlet-type/project.json b/apps/angular/context-outlet-type/project.json deleted file mode 100644 index ee2f03ccf..000000000 --- a/apps/angular/context-outlet-type/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-context-outlet-type", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/context-outlet-type/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/context-outlet-type", - "index": "apps/angular/context-outlet-type/src/index.html", - "main": "apps/angular/context-outlet-type/src/main.ts", - "polyfills": "apps/angular/context-outlet-type/src/polyfills.ts", - "tsConfig": "apps/angular/context-outlet-type/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/context-outlet-type/src/favicon.ico", - "apps/angular/context-outlet-type/src/assets" - ], - "styles": ["apps/angular/context-outlet-type/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-context-outlet-type:build:production" - }, - "development": { - "buildTarget": "angular-context-outlet-type:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-context-outlet-type:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/context-outlet-type/src/app/app.component.ts b/apps/angular/context-outlet-type/src/app/app.component.ts deleted file mode 100644 index 2683ba9d4..000000000 --- a/apps/angular/context-outlet-type/src/app/app.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { NgTemplateOutlet } from '@angular/common'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { ListComponent } from './list.component'; -import { PersonComponent } from './person.component'; - -@Component({ - standalone: true, - imports: [NgTemplateOutlet, PersonComponent, ListComponent], - selector: 'app-root', - template: ` - - - {{ name }}: {{ age }} - - - - - - {{ student.name }}: {{ student.age }} - {{ i }} - - - - - - {{ city.name }}: {{ city.country }} - {{ i }} - - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent { - person = { - name: 'toto', - age: 3, - }; - - students = [ - { name: 'toto', age: 3 }, - { name: 'titi', age: 4 }, - ]; - - cities = [ - { name: 'Paris', country: 'France' }, - { name: 'Berlin', country: 'Germany' }, - ]; -} diff --git a/apps/angular/context-outlet-type/src/app/list.component.ts b/apps/angular/context-outlet-type/src/app/list.component.ts deleted file mode 100644 index 5212a425e..000000000 --- a/apps/angular/context-outlet-type/src/app/list.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - ContentChild, - Input, - TemplateRef, -} from '@angular/core'; - -@Component({ - selector: 'list', - standalone: true, - imports: [CommonModule], - template: ` -
- -
- - No Template - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ListComponent { - @Input() list!: TItem[]; - - @ContentChild('listRef', { read: TemplateRef }) - listTemplateRef!: TemplateRef; -} diff --git a/apps/angular/context-outlet-type/src/app/person.component.ts b/apps/angular/context-outlet-type/src/app/person.component.ts deleted file mode 100644 index 1550cf274..000000000 --- a/apps/angular/context-outlet-type/src/app/person.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NgTemplateOutlet } from '@angular/common'; -import { Component, ContentChild, Input, TemplateRef } from '@angular/core'; - -interface Person { - name: string; - age: number; -} - -@Component({ - standalone: true, - imports: [NgTemplateOutlet], - selector: 'person', - template: ` - - - No Template - `, -}) -export class PersonComponent { - @Input() person!: Person; - - @ContentChild('#personRef', { read: TemplateRef }) - personTemplateRef!: TemplateRef; -} diff --git a/apps/angular/context-outlet-type/src/index.html b/apps/angular/context-outlet-type/src/index.html deleted file mode 100644 index b3ee6c60d..000000000 --- a/apps/angular/context-outlet-type/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - ContextOutletType - - - - - - - - diff --git a/apps/angular/context-outlet-type/src/main.ts b/apps/angular/context-outlet-type/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/context-outlet-type/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/context-outlet-type/tsconfig.app.json b/apps/angular/context-outlet-type/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/context-outlet-type/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/context-outlet-type/tsconfig.json b/apps/angular/context-outlet-type/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/context-outlet-type/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/crud/README.md b/apps/angular/crud/README.md deleted file mode 100644 index 0a6518b44..000000000 --- a/apps/angular/crud/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Crud application - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-crud -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/5-crud/). diff --git a/apps/angular/crud/jest.config.ts b/apps/angular/crud/jest.config.ts deleted file mode 100644 index 74a17f135..000000000 --- a/apps/angular/crud/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-crud', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/apps/angular/crud', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/crud/project.json b/apps/angular/crud/project.json deleted file mode 100644 index cb694bbd8..000000000 --- a/apps/angular/crud/project.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "name": "angular-crud", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/crud/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/crud", - "index": "apps/angular/crud/src/index.html", - "main": "apps/angular/crud/src/main.ts", - "polyfills": "apps/angular/crud/src/polyfills.ts", - "tsConfig": "apps/angular/crud/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/crud/src/favicon.ico", - "apps/angular/crud/src/assets" - ], - "styles": [ - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "apps/angular/crud/src/styles.scss" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-crud:build:production" - }, - "development": { - "buildTarget": "angular-crud:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-crud:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/crud/jest.config.ts" - } - } - }, - "tags": [] -} diff --git a/apps/angular/crud/src/app/app.component.ts b/apps/angular/crud/src/app/app.component.ts deleted file mode 100644 index 8c3d1b8ae..000000000 --- a/apps/angular/crud/src/app/app.component.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { randText } from '@ngneat/falso'; - -@Component({ - standalone: true, - imports: [CommonModule], - selector: 'app-root', - template: ` -
- {{ todo.title }} - -
- `, - styles: [], -}) -export class AppComponent implements OnInit { - todos!: any[]; - - constructor(private http: HttpClient) {} - - ngOnInit(): void { - this.http - .get('https://jsonplaceholder.typicode.com/todos') - .subscribe((todos) => { - this.todos = todos; - }); - } - - update(todo: any) { - this.http - .put( - `https://jsonplaceholder.typicode.com/todos/${todo.id}`, - JSON.stringify({ - todo: todo.id, - title: randText(), - body: todo.body, - userId: todo.userId, - }), - { - headers: { - 'Content-type': 'application/json; charset=UTF-8', - }, - }, - ) - .subscribe((todoUpdated: any) => { - this.todos[todoUpdated.id - 1] = todoUpdated; - }); - } -} diff --git a/apps/angular/crud/src/app/app.config.ts b/apps/angular/crud/src/app/app.config.ts deleted file mode 100644 index de0a3ccec..000000000 --- a/apps/angular/crud/src/app/app.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { HttpClientModule } from '@angular/common/http'; -import { ApplicationConfig, importProvidersFrom } from '@angular/core'; -export const appConfig: ApplicationConfig = { - providers: [importProvidersFrom(HttpClientModule)], -}; diff --git a/apps/angular/crud/src/index.html b/apps/angular/crud/src/index.html deleted file mode 100644 index c556437f0..000000000 --- a/apps/angular/crud/src/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Http - - - - - - - - - - - diff --git a/apps/angular/crud/src/main.ts b/apps/angular/crud/src/main.ts deleted file mode 100644 index 9bb5c3023..000000000 --- a/apps/angular/crud/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { appConfig } from './app/app.config'; - -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/angular/crud/src/test-setup.ts b/apps/angular/crud/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/crud/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/crud/tsconfig.app.json b/apps/angular/crud/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/crud/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/crud/tsconfig.json b/apps/angular/crud/tsconfig.json deleted file mode 100644 index 52eb4f718..000000000 --- a/apps/angular/crud/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/crud/tsconfig.spec.json b/apps/angular/crud/tsconfig.spec.json deleted file mode 100644 index b9534b857..000000000 --- a/apps/angular/crud/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/apps/angular/decoupling/README.md b/apps/angular/decoupling/README.md deleted file mode 100644 index 0ba00e70c..000000000 --- a/apps/angular/decoupling/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Decoupling Components - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-decoupling -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/33-decoupling/). diff --git a/apps/angular/decoupling/project.json b/apps/angular/decoupling/project.json deleted file mode 100644 index 5a76f0112..000000000 --- a/apps/angular/decoupling/project.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "angular-decoupling", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/decoupling/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/decoupling", - "index": "apps/angular/decoupling/src/index.html", - "main": "apps/angular/decoupling/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/decoupling/tsconfig.app.json", - "assets": [ - "apps/angular/decoupling/src/favicon.ico", - "apps/angular/decoupling/src/assets" - ], - "styles": ["apps/angular/decoupling/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-decoupling:build:production" - }, - "development": { - "buildTarget": "angular-decoupling:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-decoupling:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/angular/decoupling/src/app/app.component.ts b/apps/angular/decoupling/src/app/app.component.ts deleted file mode 100644 index 34082c331..000000000 --- a/apps/angular/decoupling/src/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BtnDisabledDirective } from '@angular-challenges/decoupling/brain'; -import { BtnHelmetDirective } from '@angular-challenges/decoupling/helmet'; -import { Component } from '@angular/core'; - -@Component({ - standalone: true, - imports: [BtnDisabledDirective, BtnHelmetDirective], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent {} diff --git a/apps/angular/decoupling/src/index.html b/apps/angular/decoupling/src/index.html deleted file mode 100644 index 25b5ea13c..000000000 --- a/apps/angular/decoupling/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - decoupling - - - - - - - - diff --git a/apps/angular/decoupling/src/main.ts b/apps/angular/decoupling/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/decoupling/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/decoupling/tsconfig.app.json b/apps/angular/decoupling/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/decoupling/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/decoupling/tsconfig.json b/apps/angular/decoupling/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/angular/decoupling/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/di/README.md b/apps/angular/di/README.md deleted file mode 100644 index 032601c1f..000000000 --- a/apps/angular/di/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Master Dependancy Injection - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-di -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/16-di/). diff --git a/apps/angular/di/project.json b/apps/angular/di/project.json deleted file mode 100644 index 600263715..000000000 --- a/apps/angular/di/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-di", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/di/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/di", - "index": "apps/angular/di/src/index.html", - "main": "apps/angular/di/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/di/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/di/src/favicon.ico", - "apps/angular/di/src/assets" - ], - "styles": ["apps/angular/di/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-di:build:production" - }, - "development": { - "buildTarget": "angular-di:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-di:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/di/src/app/app.component.ts b/apps/angular/di/src/app/app.component.ts deleted file mode 100644 index e57a5a5bf..000000000 --- a/apps/angular/di/src/app/app.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { TableComponent } from '@angular-challenges/angular/di'; -import { AsyncPipe, NgFor } from '@angular/common'; -import { Component, Directive } from '@angular/core'; -import { CurrencyPipe } from './currency.pipe'; -import { CurrencyService } from './currency.service'; -import { Product, products } from './product.model'; - -interface ProductContext { - $implicit: Product; -} - -@Directive({ - selector: 'ng-template[product]', - standalone: true, -}) -export class ProductDirective { - static ngTemplateContextGuard( - dir: ProductDirective, - ctx: unknown, - ): ctx is ProductContext { - return true; - } -} - -@Component({ - standalone: true, - imports: [TableComponent, CurrencyPipe, AsyncPipe, NgFor, ProductDirective], - providers: [CurrencyService], - selector: 'app-root', - template: ` - - - - - - - - - - - - - - -
- {{ col }} -
{{ product.name }}{{ product.priceA | currency | async }}{{ product.priceB | currency | async }}{{ product.priceC | currency | async }}
- `, -}) -export class AppComponent { - products = products; - displayedColumns = ['name', 'priceA', 'priceB', 'priceC']; -} diff --git a/apps/angular/di/src/app/currency.pipe.ts b/apps/angular/di/src/app/currency.pipe.ts deleted file mode 100644 index 9d90e52f1..000000000 --- a/apps/angular/di/src/app/currency.pipe.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { inject, Pipe, PipeTransform } from '@angular/core'; -import { map } from 'rxjs'; -import { CurrencyService } from './currency.service'; - -@Pipe({ - name: 'currency', - standalone: true, -}) -export class CurrencyPipe implements PipeTransform { - currencyService = inject(CurrencyService); - - transform(price: number) { - return this.currencyService.symbol$.pipe( - map((s) => `${String(price)}${s}`), - ); - } -} diff --git a/apps/angular/di/src/index.html b/apps/angular/di/src/index.html deleted file mode 100644 index c120f5b9c..000000000 --- a/apps/angular/di/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Di - - - - - - - - diff --git a/apps/angular/di/src/main.ts b/apps/angular/di/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/di/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/di/tsconfig.app.json b/apps/angular/di/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/di/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/di/tsconfig.json b/apps/angular/di/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/angular/di/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/injection-token/jest.config.ts b/apps/angular/injection-token/jest.config.ts deleted file mode 100644 index d7105f89b..000000000 --- a/apps/angular/injection-token/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-injection-token', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/injection-token', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/injection-token/project.json b/apps/angular/injection-token/project.json deleted file mode 100644 index e800af160..000000000 --- a/apps/angular/injection-token/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "angular-injection-token", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/injection-token/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/injection-token", - "index": "apps/angular/injection-token/src/index.html", - "main": "apps/angular/injection-token/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/injection-token/tsconfig.app.json", - "assets": [ - "apps/angular/injection-token/src/favicon.ico", - "apps/angular/injection-token/src/assets" - ], - "styles": ["apps/angular/injection-token/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-injection-token:build:production" - }, - "development": { - "buildTarget": "angular-injection-token:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-injection-token:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/injection-token/jest.config.ts" - } - } - } -} diff --git a/apps/angular/injection-token/src/app/app.component.ts b/apps/angular/injection-token/src/app/app.component.ts deleted file mode 100644 index 5ac8087cb..000000000 --- a/apps/angular/injection-token/src/app/app.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterLink, RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet, RouterLink], - selector: 'app-root', - template: ` -
- - -
- - `, - host: { - class: 'p-10 flex flex-col', - }, -}) -export class AppComponent {} diff --git a/apps/angular/injection-token/src/test-setup.ts b/apps/angular/injection-token/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/injection-token/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/injection-token/tsconfig.app.json b/apps/angular/injection-token/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/injection-token/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/injection-token/tsconfig.json b/apps/angular/injection-token/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/angular/injection-token/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/injection-token/tsconfig.spec.json b/apps/angular/injection-token/tsconfig.spec.json deleted file mode 100644 index 1a4817a7d..000000000 --- a/apps/angular/injection-token/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/interop-rxjs-signal/README.md b/apps/angular/interop-rxjs-signal/README.md deleted file mode 100644 index 9cf32efa5..000000000 --- a/apps/angular/interop-rxjs-signal/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Interoperability Rxjs/Signal - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-interop-rxjs-signal -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/30-interop-rxjs-signal/). diff --git a/apps/angular/interop-rxjs-signal/jest.config.ts b/apps/angular/interop-rxjs-signal/jest.config.ts deleted file mode 100644 index 23956ebcc..000000000 --- a/apps/angular/interop-rxjs-signal/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-interop-rxjs-signal', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/interop-rxjs-signal', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/interop-rxjs-signal/project.json b/apps/angular/interop-rxjs-signal/project.json deleted file mode 100644 index 5009d474e..000000000 --- a/apps/angular/interop-rxjs-signal/project.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "angular-interop-rxjs-signal", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/interop-rxjs-signal/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/interop-rxjs-signal", - "index": "apps/angular/interop-rxjs-signal/src/index.html", - "main": "apps/angular/interop-rxjs-signal/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/interop-rxjs-signal/tsconfig.app.json", - "assets": [ - "apps/angular/interop-rxjs-signal/src/favicon.ico", - "apps/angular/interop-rxjs-signal/src/assets" - ], - "styles": [ - "apps/angular/interop-rxjs-signal/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-interop-rxjs-signal:build:production" - }, - "development": { - "buildTarget": "angular-interop-rxjs-signal:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-interop-rxjs-signal:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/interop-rxjs-signal/jest.config.ts" - } - } - } -} diff --git a/apps/angular/interop-rxjs-signal/src/app/app.component.ts b/apps/angular/interop-rxjs-signal/src/app/app.component.ts deleted file mode 100644 index 7b83d1470..000000000 --- a/apps/angular/interop-rxjs-signal/src/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet], - selector: 'app-root', - template: ` - - `, - styles: [''], -}) -export class AppComponent {} diff --git a/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts b/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts deleted file mode 100644 index 3576db452..000000000 --- a/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { DatePipe } from '@angular/common'; -import { Component, Input as RouterInput } from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { Photo } from '../photo.model'; - -@Component({ - selector: 'app-photos', - standalone: true, - imports: [DatePipe, RouterLink], - template: ` - {{ photo.title }} -

- Title: - {{ photo.title }} -

-

- Owner: - {{ photo.ownername }} -

-

- Date: - {{ photo.datetaken | date }} -

-

- Tags: - {{ photo.tags }} -

- - - `, - host: { - class: 'p-5 block', - }, -}) -export default class DetailComponent { - @RouterInput({ - required: true, - transform: (value: string) => JSON.parse(decodeURIComponent(value)), - }) - photo!: Photo; -} diff --git a/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts b/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts deleted file mode 100644 index 29dc0c3f5..000000000 --- a/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { Component, OnInit, inject } from '@angular/core'; -import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { RouterLinkWithHref } from '@angular/router'; -import { LetDirective } from '@ngrx/component'; -import { provideComponentStore } from '@ngrx/component-store'; -import { debounceTime, distinctUntilChanged, skipWhile, tap } from 'rxjs'; -import { Photo } from '../photo.model'; -import { PhotoStore } from './photos.store'; - -@Component({ - selector: 'app-photos', - standalone: true, - imports: [ - ReactiveFormsModule, - MatFormFieldModule, - MatProgressBarModule, - NgIf, - NgFor, - MatInputModule, - LetDirective, - RouterLinkWithHref, - ], - template: ` -

Photos

- - - Search - - - - -
-
- - - Page :{{ vm.page }} / {{ vm.pages }} -
- - - -
No Photos found. Type a search word.
-
-
- {{ vm.error }} -
-
-
- `, - providers: [provideComponentStore(PhotoStore)], - host: { - class: 'p-5 block', - }, -}) -export default class PhotosComponent implements OnInit { - store = inject(PhotoStore); - readonly vm$ = this.store.vm$.pipe( - tap(({ search }) => { - if (!this.formInit) { - this.search.setValue(search); - this.formInit = true; - } - }), - ); - - private formInit = false; - search = new FormControl(); - - ngOnInit(): void { - this.store.search( - this.search.valueChanges.pipe( - skipWhile(() => !this.formInit), - debounceTime(300), - distinctUntilChanged(), - ), - ); - } - - trackById(index: number, photo: Photo) { - return photo.id; - } - - encode(photo: Photo) { - return encodeURIComponent(JSON.stringify(photo)); - } -} diff --git a/apps/angular/interop-rxjs-signal/src/index.html b/apps/angular/interop-rxjs-signal/src/index.html deleted file mode 100644 index 1c69fbc7a..000000000 --- a/apps/angular/interop-rxjs-signal/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - rxjs-to-signal - - - - - - - - diff --git a/apps/angular/interop-rxjs-signal/src/test-setup.ts b/apps/angular/interop-rxjs-signal/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/interop-rxjs-signal/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/interop-rxjs-signal/tsconfig.app.json b/apps/angular/interop-rxjs-signal/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/interop-rxjs-signal/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/interop-rxjs-signal/tsconfig.json b/apps/angular/interop-rxjs-signal/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/angular/interop-rxjs-signal/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/interop-rxjs-signal/tsconfig.spec.json b/apps/angular/interop-rxjs-signal/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/angular/interop-rxjs-signal/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/module-to-standalone/project.json b/apps/angular/module-to-standalone/project.json deleted file mode 100644 index 61fbd270f..000000000 --- a/apps/angular/module-to-standalone/project.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "angular-module-to-standalone", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/module-to-standalone/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/module-to-standalone", - "index": "apps/angular/module-to-standalone/src/index.html", - "main": "apps/angular/module-to-standalone/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/module-to-standalone/tsconfig.app.json", - "assets": [ - "apps/angular/module-to-standalone/src/favicon.ico", - "apps/angular/module-to-standalone/src/assets" - ], - "styles": ["apps/angular/module-to-standalone/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-module-to-standalone:build:production" - }, - "development": { - "buildTarget": "angular-module-to-standalone:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-module-to-standalone:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/angular/module-to-standalone/src/app/app.component.ts b/apps/angular/module-to-standalone/src/app/app.component.ts deleted file mode 100644 index 95eeab5b9..000000000 --- a/apps/angular/module-to-standalone/src/app/app.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-root', - template: ` -
- - - -
- - `, - host: { - class: 'flex flex-col p-4 gap-3', - }, -}) -export class AppComponent {} diff --git a/apps/angular/module-to-standalone/src/index.html b/apps/angular/module-to-standalone/src/index.html deleted file mode 100644 index 4902faa44..000000000 --- a/apps/angular/module-to-standalone/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - module-to-standalone - - - - - - - - diff --git a/apps/angular/module-to-standalone/src/main.ts b/apps/angular/module-to-standalone/src/main.ts deleted file mode 100644 index 16de2365d..000000000 --- a/apps/angular/module-to-standalone/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; - -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); diff --git a/apps/angular/module-to-standalone/tsconfig.app.json b/apps/angular/module-to-standalone/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/module-to-standalone/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/module-to-standalone/tsconfig.json b/apps/angular/module-to-standalone/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/angular/module-to-standalone/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/ngfor-enhancement/README.md b/apps/angular/ngfor-enhancement/README.md deleted file mode 100644 index 937dfb54e..000000000 --- a/apps/angular/ngfor-enhancement/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Directive Enhancement - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-ngfor-enhancement -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/3-directive-enhancement/). diff --git a/apps/angular/ngfor-enhancement/project.json b/apps/angular/ngfor-enhancement/project.json deleted file mode 100644 index 80c089ca0..000000000 --- a/apps/angular/ngfor-enhancement/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-ngfor-enhancement", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/ngfor-enhancement/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/ngfor-enhancement", - "index": "apps/angular/ngfor-enhancement/src/index.html", - "main": "apps/angular/ngfor-enhancement/src/main.ts", - "polyfills": "apps/angular/ngfor-enhancement/src/polyfills.ts", - "tsConfig": "apps/angular/ngfor-enhancement/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/ngfor-enhancement/src/favicon.ico", - "apps/angular/ngfor-enhancement/src/assets" - ], - "styles": ["apps/angular/ngfor-enhancement/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-ngfor-enhancement:build:production" - }, - "development": { - "buildTarget": "angular-ngfor-enhancement:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-ngfor-enhancement:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/ngfor-enhancement/src/app/app.component.ts b/apps/angular/ngfor-enhancement/src/app/app.component.ts deleted file mode 100644 index cd1d5f23c..000000000 --- a/apps/angular/ngfor-enhancement/src/app/app.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; - -interface Person { - name: string; -} - -@Component({ - standalone: true, - imports: [NgFor, NgIf], - selector: 'app-root', - template: ` - -
- {{ person.name }} -
-
- The list is empty !! - `, - styles: [], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent { - persons: Person[] = []; -} diff --git a/apps/angular/ngfor-enhancement/src/index.html b/apps/angular/ngfor-enhancement/src/index.html deleted file mode 100644 index c38d89dee..000000000 --- a/apps/angular/ngfor-enhancement/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - NgForEnhance - - - - - - - - diff --git a/apps/angular/ngfor-enhancement/src/main.ts b/apps/angular/ngfor-enhancement/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/ngfor-enhancement/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/ngfor-enhancement/tsconfig.app.json b/apps/angular/ngfor-enhancement/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/ngfor-enhancement/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/ngfor-enhancement/tsconfig.json b/apps/angular/ngfor-enhancement/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/ngfor-enhancement/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/permissions/README.md b/apps/angular/permissions/README.md deleted file mode 100644 index 99b2e5582..000000000 --- a/apps/angular/permissions/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Structural Directive - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-permissions -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/6-permissions/). diff --git a/apps/angular/permissions/project.json b/apps/angular/permissions/project.json deleted file mode 100644 index a594781d3..000000000 --- a/apps/angular/permissions/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-permissions", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/permissions/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/permissions", - "index": "apps/angular/permissions/src/index.html", - "main": "apps/angular/permissions/src/main.ts", - "polyfills": "apps/angular/permissions/src/polyfills.ts", - "tsConfig": "apps/angular/permissions/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/permissions/src/favicon.ico", - "apps/angular/permissions/src/assets" - ], - "styles": ["apps/angular/permissions/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-permissions:build:production" - }, - "development": { - "buildTarget": "angular-permissions:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-permissions:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/permissions/src/app/app.component.ts b/apps/angular/permissions/src/app/app.component.ts deleted file mode 100644 index d89a2f579..000000000 --- a/apps/angular/permissions/src/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet], - selector: 'app-root', - template: ` - - `, - styles: [], -}) -export class AppComponent {} diff --git a/apps/angular/permissions/src/app/dashboard/manager.component.ts b/apps/angular/permissions/src/app/dashboard/manager.component.ts deleted file mode 100644 index b92fc7925..000000000 --- a/apps/angular/permissions/src/app/dashboard/manager.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { ButtonComponent } from '../button.component'; - -@Component({ - selector: 'app-dashboard', - standalone: true, - imports: [RouterLink, ButtonComponent], - template: ` -

dashboard for Manager works!

- - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ManagerDashboardComponent {} diff --git a/apps/angular/permissions/src/app/information.component.ts b/apps/angular/permissions/src/app/information.component.ts deleted file mode 100644 index e4adeb1b9..000000000 --- a/apps/angular/permissions/src/app/information.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { UserStore } from './user.store'; - -@Component({ - selector: 'app-information', - standalone: true, - imports: [CommonModule], - template: ` -

Information Panel

- -
visible only for super admin
-
visible if manager
-
visible if manager and/or reader
-
visible if manager and/or writer
-
visible if client
-
visible for everyone
- `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class InformationComponent { - user$ = this.userStore.user$; - constructor(private userStore: UserStore) {} -} diff --git a/apps/angular/permissions/src/index.html b/apps/angular/permissions/src/index.html deleted file mode 100644 index 14ab31c3b..000000000 --- a/apps/angular/permissions/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Permissions - - - - - - - - diff --git a/apps/angular/permissions/src/main.ts b/apps/angular/permissions/src/main.ts deleted file mode 100644 index 7961924bf..000000000 --- a/apps/angular/permissions/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/angular/permissions/tsconfig.app.json b/apps/angular/permissions/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/permissions/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/permissions/tsconfig.json b/apps/angular/permissions/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/permissions/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/pipe-easy/README.md b/apps/angular/pipe-easy/README.md deleted file mode 100644 index 8501be8c7..000000000 --- a/apps/angular/pipe-easy/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Pure Pipe - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-pipe-easy -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/8-pipe-pure/). diff --git a/apps/angular/pipe-easy/project.json b/apps/angular/pipe-easy/project.json deleted file mode 100644 index b1fda113e..000000000 --- a/apps/angular/pipe-easy/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-pipe-easy", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/pipe-easy/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/pipe-easy", - "index": "apps/angular/pipe-easy/src/index.html", - "main": "apps/angular/pipe-easy/src/main.ts", - "polyfills": "apps/angular/pipe-easy/src/polyfills.ts", - "tsConfig": "apps/angular/pipe-easy/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/pipe-easy/src/favicon.ico", - "apps/angular/pipe-easy/src/assets" - ], - "styles": ["apps/angular/pipe-easy/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-pipe-easy:build:production" - }, - "development": { - "buildTarget": "angular-pipe-easy:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-pipe-easy:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/pipe-easy/src/app/app.component.ts b/apps/angular/pipe-easy/src/app/app.component.ts deleted file mode 100644 index 3c19fa169..000000000 --- a/apps/angular/pipe-easy/src/app/app.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NgFor } from '@angular/common'; -import { Component } from '@angular/core'; - -@Component({ - standalone: true, - imports: [NgFor], - selector: 'app-root', - template: ` -
- {{ heavyComputation(person, index) }} -
- `, -}) -export class AppComponent { - persons = ['toto', 'jack']; - - heavyComputation(name: string, index: number) { - // very heavy computation - return `${name} - ${index}`; - } -} diff --git a/apps/angular/pipe-easy/src/index.html b/apps/angular/pipe-easy/src/index.html deleted file mode 100644 index eacdd37b7..000000000 --- a/apps/angular/pipe-easy/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - PipeEasy - - - - - - - - diff --git a/apps/angular/pipe-easy/src/main.ts b/apps/angular/pipe-easy/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/pipe-easy/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-easy/tsconfig.app.json b/apps/angular/pipe-easy/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/pipe-easy/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/pipe-easy/tsconfig.json b/apps/angular/pipe-easy/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/pipe-easy/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/pipe-hard/README.md b/apps/angular/pipe-hard/README.md deleted file mode 100644 index ba801bd0c..000000000 --- a/apps/angular/pipe-hard/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Utility Wrapper Pipe - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-pipe-hard -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/10-pipe-utility/). diff --git a/apps/angular/pipe-hard/project.json b/apps/angular/pipe-hard/project.json deleted file mode 100644 index 677edccba..000000000 --- a/apps/angular/pipe-hard/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-pipe-hard", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/pipe-hard/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/pipe-hard", - "index": "apps/angular/pipe-hard/src/index.html", - "main": "apps/angular/pipe-hard/src/main.ts", - "polyfills": "apps/angular/pipe-hard/src/polyfills.ts", - "tsConfig": "apps/angular/pipe-hard/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/pipe-hard/src/favicon.ico", - "apps/angular/pipe-hard/src/assets" - ], - "styles": ["apps/angular/pipe-hard/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-pipe-hard:build:production" - }, - "development": { - "buildTarget": "angular-pipe-hard:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-pipe-hard:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/pipe-hard/src/app/app.component.ts b/apps/angular/pipe-hard/src/app/app.component.ts deleted file mode 100644 index d91fc7436..000000000 --- a/apps/angular/pipe-hard/src/app/app.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { NgFor } from '@angular/common'; -import { Component } from '@angular/core'; -import { PersonUtils } from './person.utils'; - -@Component({ - standalone: true, - imports: [NgFor], - selector: 'app-root', - template: ` -
- {{ activity.name }} : -
- {{ showName(person.name, index) }} - {{ isAllowed(person.age, isFirst, activity.minimumAge) }} -
-
- `, -}) -export class AppComponent { - persons = [ - { name: 'Toto', age: 10 }, - { name: 'Jack', age: 15 }, - { name: 'John', age: 30 }, - ]; - - activities = [ - { name: 'biking', minimumAge: 12 }, - { name: 'hiking', minimumAge: 25 }, - { name: 'dancing', minimumAge: 1 }, - ]; - - showName = PersonUtils.showName; - - isAllowed = PersonUtils.isAllowed; -} diff --git a/apps/angular/pipe-hard/src/index.html b/apps/angular/pipe-hard/src/index.html deleted file mode 100644 index 0b81de34b..000000000 --- a/apps/angular/pipe-hard/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - PipeHard - - - - - - - - diff --git a/apps/angular/pipe-hard/src/main.ts b/apps/angular/pipe-hard/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/pipe-hard/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-hard/tsconfig.app.json b/apps/angular/pipe-hard/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/pipe-hard/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/pipe-hard/tsconfig.json b/apps/angular/pipe-hard/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/pipe-hard/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/pipe-intermediate/README.md b/apps/angular/pipe-intermediate/README.md deleted file mode 100644 index 72809fd19..000000000 --- a/apps/angular/pipe-intermediate/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Wrap Function Pipe - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-pipe-intermediate -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/9-pipe-wrapFn/). diff --git a/apps/angular/pipe-intermediate/project.json b/apps/angular/pipe-intermediate/project.json deleted file mode 100644 index 689731511..000000000 --- a/apps/angular/pipe-intermediate/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-pipe-intermediate", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/pipe-intermediate/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/pipe-intermediate", - "index": "apps/angular/pipe-intermediate/src/index.html", - "main": "apps/angular/pipe-intermediate/src/main.ts", - "polyfills": "apps/angular/pipe-intermediate/src/polyfills.ts", - "tsConfig": "apps/angular/pipe-intermediate/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/pipe-intermediate/src/favicon.ico", - "apps/angular/pipe-intermediate/src/assets" - ], - "styles": ["apps/angular/pipe-intermediate/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-pipe-intermediate:build:production" - }, - "development": { - "buildTarget": "angular-pipe-intermediate:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-pipe-intermediate:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/pipe-intermediate/src/app/app.component.ts b/apps/angular/pipe-intermediate/src/app/app.component.ts deleted file mode 100644 index d9c163c93..000000000 --- a/apps/angular/pipe-intermediate/src/app/app.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { NgFor } from '@angular/common'; -import { Component } from '@angular/core'; - -@Component({ - standalone: true, - imports: [NgFor], - selector: 'app-root', - template: ` -
- {{ showName(person.name, index) }} - {{ isAllowed(person.age, isFirst) }} -
- `, -}) -export class AppComponent { - persons = [ - { name: 'Toto', age: 10 }, - { name: 'Jack', age: 15 }, - { name: 'John', age: 30 }, - ]; - - showName(name: string, index: number) { - // very heavy computation - return `${name} - ${index}`; - } - - isAllowed(age: number, isFirst: boolean) { - if (isFirst) { - return 'always allowed'; - } else { - return age > 25 ? 'allowed' : 'declined'; - } - } -} diff --git a/apps/angular/pipe-intermediate/src/index.html b/apps/angular/pipe-intermediate/src/index.html deleted file mode 100644 index 1a8b2ee22..000000000 --- a/apps/angular/pipe-intermediate/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - PipeIntermediate - - - - - - - - diff --git a/apps/angular/pipe-intermediate/src/main.ts b/apps/angular/pipe-intermediate/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/angular/pipe-intermediate/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/pipe-intermediate/tsconfig.app.json b/apps/angular/pipe-intermediate/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/pipe-intermediate/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/pipe-intermediate/tsconfig.json b/apps/angular/pipe-intermediate/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/angular/pipe-intermediate/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/projection/jest.config.ts b/apps/angular/projection/jest.config.ts deleted file mode 100644 index 289a9b0e3..000000000 --- a/apps/angular/projection/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-projection', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/apps/angular/projection', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/projection/project.json b/apps/angular/projection/project.json deleted file mode 100644 index 67be2738f..000000000 --- a/apps/angular/projection/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "angular-projection", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/projection/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/projection", - "index": "apps/angular/projection/src/index.html", - "browser": "apps/angular/projection/src/main.ts", - "polyfills": ["apps/angular/projection/src/polyfills.ts"], - "tsConfig": "apps/angular/projection/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/projection/src/favicon.ico", - "apps/angular/projection/src/assets" - ], - "styles": ["apps/angular/projection/src/styles.scss"], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-projection:build:production" - }, - "development": { - "buildTarget": "angular-projection:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-projection:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/projection/jest.config.ts" - } - } - }, - "tags": [] -} diff --git a/apps/angular/projection/src/app/app.component.ts b/apps/angular/projection/src/app/app.component.ts deleted file mode 100644 index b1d076a9f..000000000 --- a/apps/angular/projection/src/app/app.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component } from '@angular/core'; -import { CityCardComponent } from './component/city-card/city-card.component'; -import { StudentCardComponent } from './component/student-card/student-card.component'; -import { TeacherCardComponent } from './component/teacher-card/teacher-card.component'; - -@Component({ - selector: 'app-root', - template: ` -
- - - -
- `, - standalone: true, - imports: [TeacherCardComponent, StudentCardComponent, CityCardComponent], -}) -export class AppComponent {} diff --git a/apps/angular/projection/src/app/component/city-card/city-card.component.ts b/apps/angular/projection/src/app/component/city-card/city-card.component.ts deleted file mode 100644 index 30c8f88ec..000000000 --- a/apps/angular/projection/src/app/component/city-card/city-card.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-city-card', - template: 'TODO City', - standalone: true, - imports: [], -}) -export class CityCardComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} diff --git a/apps/angular/projection/src/app/component/student-card/student-card.component.ts b/apps/angular/projection/src/app/component/student-card/student-card.component.ts deleted file mode 100644 index 441cda189..000000000 --- a/apps/angular/projection/src/app/component/student-card/student-card.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { FakeHttpService } from '../../data-access/fake-http.service'; -import { StudentStore } from '../../data-access/student.store'; -import { CardType } from '../../model/card.model'; -import { Student } from '../../model/student.model'; -import { CardComponent } from '../../ui/card/card.component'; - -@Component({ - selector: 'app-student-card', - template: ` - - `, - standalone: true, - styles: [ - ` - ::ng-deep .bg-light-green { - background-color: rgba(0, 250, 0, 0.1); - } - `, - ], - imports: [CardComponent], -}) -export class StudentCardComponent implements OnInit { - students: Student[] = []; - cardType = CardType.STUDENT; - - constructor( - private http: FakeHttpService, - private store: StudentStore, - ) {} - - ngOnInit(): void { - this.http.fetchStudents$.subscribe((s) => this.store.addAll(s)); - - this.store.students$.subscribe((s) => (this.students = s)); - } -} diff --git a/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts b/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts deleted file mode 100644 index 995cb7c2f..000000000 --- a/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { FakeHttpService } from '../../data-access/fake-http.service'; -import { TeacherStore } from '../../data-access/teacher.store'; -import { CardType } from '../../model/card.model'; -import { Teacher } from '../../model/teacher.model'; -import { CardComponent } from '../../ui/card/card.component'; - -@Component({ - selector: 'app-teacher-card', - template: ` - - `, - styles: [ - ` - ::ng-deep .bg-light-red { - background-color: rgba(250, 0, 0, 0.1); - } - `, - ], - standalone: true, - imports: [CardComponent], -}) -export class TeacherCardComponent implements OnInit { - teachers: Teacher[] = []; - cardType = CardType.TEACHER; - - constructor( - private http: FakeHttpService, - private store: TeacherStore, - ) {} - - ngOnInit(): void { - this.http.fetchTeachers$.subscribe((t) => this.store.addAll(t)); - - this.store.teachers$.subscribe((t) => (this.teachers = t)); - } -} diff --git a/apps/angular/projection/src/app/data-access/city.store.ts b/apps/angular/projection/src/app/data-access/city.store.ts deleted file mode 100644 index 711dad1d7..000000000 --- a/apps/angular/projection/src/app/data-access/city.store.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; -import { City } from '../model/city.model'; - -@Injectable({ - providedIn: 'root', -}) -export class CityStore { - private cities = new BehaviorSubject([]); - cities$ = this.cities.asObservable(); - - addAll(cities: City[]) { - this.cities.next(cities); - } - - addOne(student: City) { - this.cities.next([...this.cities.value, student]); - } - - deleteOne(id: number) { - this.cities.next(this.cities.value.filter((s) => s.id !== id)); - } -} diff --git a/apps/angular/projection/src/app/data-access/student.store.ts b/apps/angular/projection/src/app/data-access/student.store.ts deleted file mode 100644 index 7918118c3..000000000 --- a/apps/angular/projection/src/app/data-access/student.store.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; -import { Student } from '../model/student.model'; - -@Injectable({ - providedIn: 'root', -}) -export class StudentStore { - private students = new BehaviorSubject([]); - students$ = this.students.asObservable(); - - addAll(students: Student[]) { - this.students.next(students); - } - - addOne(student: Student) { - this.students.next([...this.students.value, student]); - } - - deleteOne(id: number) { - this.students.next(this.students.value.filter((s) => s.id !== id)); - } -} diff --git a/apps/angular/projection/src/app/data-access/teacher.store.ts b/apps/angular/projection/src/app/data-access/teacher.store.ts deleted file mode 100644 index 93f68c4b1..000000000 --- a/apps/angular/projection/src/app/data-access/teacher.store.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; -import { Teacher } from '../model/teacher.model'; - -@Injectable({ - providedIn: 'root', -}) -export class TeacherStore { - private teachers = new BehaviorSubject([]); - teachers$ = this.teachers.asObservable(); - - addAll(teachers: Teacher[]) { - this.teachers.next(teachers); - } - - addOne(teacher: Teacher) { - this.teachers.next([...this.teachers.value, teacher]); - } - - deleteOne(id: number) { - this.teachers.next(this.teachers.value.filter((t) => t.id !== id)); - } -} diff --git a/apps/angular/projection/src/app/ui/card/card.component.ts b/apps/angular/projection/src/app/ui/card/card.component.ts deleted file mode 100644 index f06c9ae00..000000000 --- a/apps/angular/projection/src/app/ui/card/card.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { Component, Input } from '@angular/core'; -import { randStudent, randTeacher } from '../../data-access/fake-http.service'; -import { StudentStore } from '../../data-access/student.store'; -import { TeacherStore } from '../../data-access/teacher.store'; -import { CardType } from '../../model/card.model'; -import { ListItemComponent } from '../list-item/list-item.component'; - -@Component({ - selector: 'app-card', - template: ` -
- - - -
- -
- - -
- `, - standalone: true, - imports: [NgIf, NgFor, ListItemComponent], -}) -export class CardComponent { - @Input() list: any[] | null = null; - @Input() type!: CardType; - @Input() customClass = ''; - - CardType = CardType; - - constructor( - private teacherStore: TeacherStore, - private studentStore: StudentStore, - ) {} - - addNewItem() { - if (this.type === CardType.TEACHER) { - this.teacherStore.addOne(randTeacher()); - } else if (this.type === CardType.STUDENT) { - this.studentStore.addOne(randStudent()); - } - } -} diff --git a/apps/angular/projection/src/app/ui/list-item/list-item.component.ts b/apps/angular/projection/src/app/ui/list-item/list-item.component.ts deleted file mode 100644 index c0f9cff7f..000000000 --- a/apps/angular/projection/src/app/ui/list-item/list-item.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { StudentStore } from '../../data-access/student.store'; -import { TeacherStore } from '../../data-access/teacher.store'; -import { CardType } from '../../model/card.model'; - -@Component({ - selector: 'app-list-item', - template: ` -
- {{ name }} - -
- `, - standalone: true, -}) -export class ListItemComponent { - @Input() id!: number; - @Input() name!: string; - @Input() type!: CardType; - - constructor( - private teacherStore: TeacherStore, - private studentStore: StudentStore, - ) {} - - delete(id: number) { - if (this.type === CardType.TEACHER) { - this.teacherStore.deleteOne(id); - } else if (this.type === CardType.STUDENT) { - this.studentStore.deleteOne(id); - } - } -} diff --git a/apps/angular/projection/src/index.html b/apps/angular/projection/src/index.html deleted file mode 100644 index 7f19c5dfd..000000000 --- a/apps/angular/projection/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Projection - - - - - - - - diff --git a/apps/angular/projection/src/main.ts b/apps/angular/projection/src/main.ts deleted file mode 100644 index 9cd15da95..000000000 --- a/apps/angular/projection/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent); diff --git a/apps/angular/projection/src/polyfills.ts b/apps/angular/projection/src/polyfills.ts deleted file mode 100644 index e4555ed11..000000000 --- a/apps/angular/projection/src/polyfills.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes recent versions of Safari, Chrome (including - * Opera), Edge on the desktop, and iOS and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/apps/angular/projection/src/test-setup.ts b/apps/angular/projection/src/test-setup.ts deleted file mode 100644 index 1100b3e8a..000000000 --- a/apps/angular/projection/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/projection/tsconfig.app.json b/apps/angular/projection/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/angular/projection/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/angular/projection/tsconfig.json b/apps/angular/projection/tsconfig.json deleted file mode 100644 index 52eb4f718..000000000 --- a/apps/angular/projection/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/projection/tsconfig.spec.json b/apps/angular/projection/tsconfig.spec.json deleted file mode 100644 index 7aa46d88c..000000000 --- a/apps/angular/projection/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/apps/angular/react-in-angular/jest.config.ts b/apps/angular/react-in-angular/jest.config.ts deleted file mode 100644 index 92d5f2583..000000000 --- a/apps/angular/react-in-angular/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-react-in-angular', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/react-in-angular', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/react-in-angular/project.json b/apps/angular/react-in-angular/project.json deleted file mode 100644 index 8153ec8d3..000000000 --- a/apps/angular/react-in-angular/project.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "angular-react-in-angular", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/react-in-angular/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/react-in-angular", - "index": "apps/angular/react-in-angular/src/index.html", - "browser": "apps/angular/react-in-angular/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/react-in-angular/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/react-in-angular/src/favicon.ico", - "apps/angular/react-in-angular/src/assets" - ], - "styles": ["apps/angular/react-in-angular/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-react-in-angular:build:production" - }, - "development": { - "buildTarget": "angular-react-in-angular:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-react-in-angular:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/react-in-angular/jest.config.ts" - } - } - } -} diff --git a/apps/angular/react-in-angular/src/app/app.component.ts b/apps/angular/react-in-angular/src/app/app.component.ts deleted file mode 100644 index a914cc65f..000000000 --- a/apps/angular/react-in-angular/src/app/app.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Component, signal } from '@angular/core'; -import { PostComponent } from './react/post.component'; - -type Post = { title: string; description: string }; - -@Component({ - standalone: true, - imports: [PostComponent], - selector: 'app-root', - template: ` -
-
- @for (post of posts; track post.title) { -
- -
- } -
-
- Selected Post: - - {{ selectedPost()?.title ?? '-' }} - -
-
- `, - styles: [''], -}) -export class AppComponent { - readonly posts = [ - { - title: 'A Deep Dive into Angular', - description: - "Explore Angular's core features, its evolution, and best practices in development for creating dynamic, efficient web applications in our comprehensive guide.", - pictureLink: - 'https://images.unsplash.com/photo-1471958680802-1345a694ba6d', - }, - { - title: 'The Perfect Combination', - description: - 'Unveil the power of combining Angular & React in web development, maximizing efficiency and flexibility for building scalable, sophisticated applications.', - pictureLink: - 'https://images.unsplash.com/photo-1518717202715-9fa9d099f58a', - }, - { - title: 'Taking Angular to the Next Level', - description: - "Discover how integrating React with Angular elevates web development, blending Angular's structure with React's UI prowess for advanced applications.", - pictureLink: - 'https://images.unsplash.com/photo-1532103050105-860af53bc6aa', - }, - ]; - - readonly selectedPost = signal(null); - - selectPost(post: Post) { - this.selectedPost.set(post); - } -} diff --git a/apps/angular/react-in-angular/src/app/react/ReactPost.tsx b/apps/angular/react-in-angular/src/app/react/ReactPost.tsx deleted file mode 100644 index 6ff7b4df4..000000000 --- a/apps/angular/react-in-angular/src/app/react/ReactPost.tsx +++ /dev/null @@ -1,27 +0,0 @@ -// import React from 'react'; - -export default function ReactPost(props: { - title?: string, - description?: string, - pictureLink?: string, - selected?: boolean, - handleClick: () => void -}) { - return ( -
-
- {props.title} -
-
{props.title}
-

- {props.description} -

- -
-
-
- ); -} diff --git a/apps/angular/react-in-angular/src/app/react/post.component.ts b/apps/angular/react-in-angular/src/app/react/post.component.ts deleted file mode 100644 index 2a35eaca6..000000000 --- a/apps/angular/react-in-angular/src/app/react/post.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, EventEmitter, input, Output } from '@angular/core'; - -type Post = { title: string; description: string; pictureLink: string }; - -@Component({ - standalone: true, - selector: 'app-post', - template: ` -
- `, - styles: [''], -}) -export class PostComponent { - post = input(undefined); - isSelected = input(false); - @Output() selectPost = new EventEmitter(); -} diff --git a/apps/angular/react-in-angular/src/test-setup.ts b/apps/angular/react-in-angular/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/react-in-angular/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/react-in-angular/tsconfig.app.json b/apps/angular/react-in-angular/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/react-in-angular/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/react-in-angular/tsconfig.json b/apps/angular/react-in-angular/tsconfig.json deleted file mode 100644 index 7a9f4b7a7..000000000 --- a/apps/angular/react-in-angular/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json", - }, - { - "path": "./tsconfig.spec.json", - }, - { - "path": "./tsconfig.editor.json", - }, - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true, - }, -} diff --git a/apps/angular/react-in-angular/tsconfig.spec.json b/apps/angular/react-in-angular/tsconfig.spec.json deleted file mode 100644 index 1a4817a7d..000000000 --- a/apps/angular/react-in-angular/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/router-input/project.json b/apps/angular/router-input/project.json deleted file mode 100644 index 523fff02e..000000000 --- a/apps/angular/router-input/project.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "angular-router-input", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/router-input/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/router-input", - "index": "apps/angular/router-input/src/index.html", - "main": "apps/angular/router-input/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/router-input/tsconfig.app.json", - "assets": [ - "apps/angular/router-input/src/favicon.ico", - "apps/angular/router-input/src/assets" - ], - "styles": ["apps/angular/router-input/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-router-input:build:production" - }, - "development": { - "buildTarget": "angular-router-input:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-router-input:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/angular/router-input/src/app/app.component.ts b/apps/angular/router-input/src/app/app.component.ts deleted file mode 100644 index 1ef7e32aa..000000000 --- a/apps/angular/router-input/src/app/app.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component } from '@angular/core'; -import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { RouterLink, RouterModule } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterLink, RouterModule, ReactiveFormsModule], - selector: 'app-root', - template: ` - - - - - - - - `, -}) -export class AppComponent { - userName = new FormControl(); - testId = new FormControl(); -} diff --git a/apps/angular/router-input/src/app/home.component.ts b/apps/angular/router-input/src/app/home.component.ts deleted file mode 100644 index 2ef8c5eb4..000000000 --- a/apps/angular/router-input/src/app/home.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -@Component({ - selector: 'app-home', - standalone: true, - imports: [], - template: ` -
Home
- `, -}) -export default class HomeComponent {} diff --git a/apps/angular/router-input/src/index.html b/apps/angular/router-input/src/index.html deleted file mode 100644 index daa121537..000000000 --- a/apps/angular/router-input/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - router-input - - - - - - - - diff --git a/apps/angular/router-input/tsconfig.app.json b/apps/angular/router-input/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/router-input/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/router-input/tsconfig.json b/apps/angular/router-input/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/angular/router-input/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/signal-input/README.md b/apps/angular/signal-input/README.md deleted file mode 100644 index 78ef74d74..000000000 --- a/apps/angular/signal-input/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Signal Input - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-signal-input -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/43-signal-input/). diff --git a/apps/angular/signal-input/project.json b/apps/angular/signal-input/project.json deleted file mode 100644 index 00f1a6797..000000000 --- a/apps/angular/signal-input/project.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "angular-signal-input", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/signal-input/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/signal-input", - "index": "apps/angular/signal-input/src/index.html", - "browser": "apps/angular/signal-input/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/signal-input/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/signal-input/src/favicon.ico", - "apps/angular/signal-input/src/assets" - ], - "styles": ["apps/angular/signal-input/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-signal-input:build:production" - }, - "development": { - "buildTarget": "angular-signal-input:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-signal-input:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - } - } -} diff --git a/apps/angular/signal-input/src/app/app.component.ts b/apps/angular/signal-input/src/app/app.component.ts deleted file mode 100644 index 22e64386e..000000000 --- a/apps/angular/signal-input/src/app/app.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { JsonPipe } from '@angular/common'; -import { Component } from '@angular/core'; -import { UserComponent } from './user.component'; - -@Component({ - standalone: true, - imports: [UserComponent, JsonPipe], - selector: 'app-root', - template: ` -
-
- Name: - - @if (showUser && !name.value) { -
name required
- } -
-
- LastName: - -
-
- Age: - -
- -
- @if (showUser && !!name.value) { - - } - `, - host: { - class: 'p-10 block flex flex-col gap-10', - }, -}) -export class AppComponent { - showUser = false; -} diff --git a/apps/angular/signal-input/src/index.html b/apps/angular/signal-input/src/index.html deleted file mode 100644 index 4fc2af8ca..000000000 --- a/apps/angular/signal-input/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - angular-signal-input - - - - - - - - diff --git a/apps/angular/signal-input/tsconfig.app.json b/apps/angular/signal-input/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/signal-input/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/signal-input/tsconfig.json b/apps/angular/signal-input/tsconfig.json deleted file mode 100644 index b94f8837d..000000000 --- a/apps/angular/signal-input/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/simple-animations/jest.config.ts b/apps/angular/simple-animations/jest.config.ts deleted file mode 100644 index 8f5d36cf8..000000000 --- a/apps/angular/simple-animations/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'angular-simple-animations', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/angular/simple-animations', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/angular/simple-animations/project.json b/apps/angular/simple-animations/project.json deleted file mode 100644 index 4ba302da8..000000000 --- a/apps/angular/simple-animations/project.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "angular-simple-animations", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/simple-animations/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/simple-animations", - "index": "apps/angular/simple-animations/src/index.html", - "browser": "apps/angular/simple-animations/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/simple-animations/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/simple-animations/src/favicon.ico", - "apps/angular/simple-animations/src/assets" - ], - "styles": ["apps/angular/simple-animations/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-simple-animations:build:production" - }, - "development": { - "buildTarget": "angular-simple-animations:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-simple-animations:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/angular/simple-animations/jest.config.ts" - } - } - } -} diff --git a/apps/angular/simple-animations/src/app/app.component.ts b/apps/angular/simple-animations/src/app/app.component.ts deleted file mode 100644 index 9f537b3fb..000000000 --- a/apps/angular/simple-animations/src/app/app.component.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - standalone: true, - imports: [], - selector: 'app-root', - styles: ` - section { - @apply flex flex-1 flex-col gap-5; - } - - .list-item { - @apply flex flex-row border-b px-5 pb-2; - - span { - @apply flex-1; - } - } - `, - template: ` -
-
-
-

2008

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae - mollitia sequi accusantium, distinctio similique laudantium eveniet - quidem sit placeat possimus tempore dolorum inventore corporis atque - quae ad, nobis explicabo delectus. -

-
- -
-

2010

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae - mollitia sequi accusantium, distinctio similique laudantium eveniet - quidem sit placeat possimus tempore dolorum inventore corporis atque - quae ad, nobis explicabo delectus. -

-
- -
-

2012

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae - mollitia sequi accusantium, distinctio similique laudantium eveniet - quidem sit placeat possimus tempore dolorum inventore corporis atque - quae ad, nobis explicabo delectus. -

-
-
- -
-
- Name: - Samuel -
- -
- Age: - 28 -
- -
- Birthdate: - 02.11.1995 -
- -
- City: - Berlin -
- -
- Language: - English -
- -
- Like Pizza: - Hell yeah -
-
-
- `, -}) -export class AppComponent {} diff --git a/apps/angular/simple-animations/src/main.ts b/apps/angular/simple-animations/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/angular/simple-animations/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/angular/simple-animations/src/test-setup.ts b/apps/angular/simple-animations/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/angular/simple-animations/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/simple-animations/tsconfig.app.json b/apps/angular/simple-animations/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/simple-animations/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/simple-animations/tsconfig.json b/apps/angular/simple-animations/tsconfig.json deleted file mode 100644 index 7a9f4b7a7..000000000 --- a/apps/angular/simple-animations/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json", - }, - { - "path": "./tsconfig.spec.json", - }, - { - "path": "./tsconfig.editor.json", - }, - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true, - }, -} diff --git a/apps/angular/simple-animations/tsconfig.spec.json b/apps/angular/simple-animations/tsconfig.spec.json deleted file mode 100644 index 1a4817a7d..000000000 --- a/apps/angular/simple-animations/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/angular/styling/README.md b/apps/angular/styling/README.md deleted file mode 100644 index d47efe3e8..000000000 --- a/apps/angular/styling/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Highly Customizable CSS - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve angular-styling -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/13-styling/). diff --git a/apps/angular/styling/project.json b/apps/angular/styling/project.json deleted file mode 100644 index de968463e..000000000 --- a/apps/angular/styling/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "angular-styling", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/angular/styling/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/styling", - "index": "apps/angular/styling/src/index.html", - "main": "apps/angular/styling/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/styling/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/styling/src/favicon.ico", - "apps/angular/styling/src/assets" - ], - "styles": ["apps/angular/styling/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-styling:build:production" - }, - "development": { - "buildTarget": "angular-styling:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-styling:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/angular/styling/src/app/page.component.ts b/apps/angular/styling/src/app/page.component.ts deleted file mode 100644 index 067453294..000000000 --- a/apps/angular/styling/src/app/page.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { Component } from '@angular/core'; -import { TextStaticComponent } from './static-text.component'; -import { TextComponent } from './text.component'; - -@Component({ - selector: 'page', - standalone: true, - imports: [TextStaticComponent, TextComponent], - template: ` - - - - This is a blue text - `, -}) -export class PageComponent {} diff --git a/apps/angular/styling/src/app/static-text.component.ts b/apps/angular/styling/src/app/static-text.component.ts deleted file mode 100644 index cdfd1c19f..000000000 --- a/apps/angular/styling/src/app/static-text.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { Component, Input } from '@angular/core'; -import { TextComponent } from './text.component'; - -export type StaticTextType = 'normal' | 'warning' | 'error'; - -@Component({ - selector: 'static-text', - standalone: true, - imports: [TextComponent], - template: ` - This is a static text - `, -}) -export class TextStaticComponent { - @Input() set type(type: StaticTextType) { - switch (type) { - case 'error': { - this.font = 30; - this.color = 'red'; - break; - } - case 'warning': { - this.font = 25; - this.color = 'orange'; - break; - } - } - } - - font = 10; - color = 'black'; -} diff --git a/apps/angular/styling/src/app/text.component.ts b/apps/angular/styling/src/app/text.component.ts deleted file mode 100644 index 452e76a8e..000000000 --- a/apps/angular/styling/src/app/text.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'text', - standalone: true, - template: ` -

- -

- `, -}) -export class TextComponent { - @Input() font = 10; - @Input() color = 'black'; -} diff --git a/apps/angular/styling/src/index.html b/apps/angular/styling/src/index.html deleted file mode 100644 index 7ea1636bf..000000000 --- a/apps/angular/styling/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Styling - - - - - - - - diff --git a/apps/angular/styling/src/main.ts b/apps/angular/styling/src/main.ts deleted file mode 100644 index 698b48462..000000000 --- a/apps/angular/styling/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { PageComponent } from './app/page.component'; - -bootstrapApplication(PageComponent).catch((err) => console.error(err)); diff --git a/apps/angular/styling/tsconfig.app.json b/apps/angular/styling/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/styling/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/styling/tsconfig.json b/apps/angular/styling/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/angular/styling/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/view-transition/project.json b/apps/angular/view-transition/project.json deleted file mode 100644 index d0a27fd5f..000000000 --- a/apps/angular/view-transition/project.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "angular-view-transition", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/angular/view-transition/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/angular/view-transition", - "index": "apps/angular/view-transition/src/index.html", - "browser": "apps/angular/view-transition/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/angular/view-transition/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/angular/view-transition/src/favicon.ico", - "apps/angular/view-transition/src/assets" - ], - "styles": ["apps/angular/view-transition/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "angular-view-transition:build:production" - }, - "development": { - "buildTarget": "angular-view-transition:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "angular-view-transition:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - } - } -} diff --git a/apps/angular/view-transition/src/app/app.component.ts b/apps/angular/view-transition/src/app/app.component.ts deleted file mode 100644 index da56c04c0..000000000 --- a/apps/angular/view-transition/src/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet], - selector: 'app-root', - template: ` - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent {} diff --git a/apps/angular/view-transition/src/app/post/post.component.ts b/apps/angular/view-transition/src/app/post/post.component.ts deleted file mode 100644 index 1e1c6fd89..000000000 --- a/apps/angular/view-transition/src/app/post/post.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { NgOptimizedImage } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - computed, - input, -} from '@angular/core'; -import { RouterLink } from '@angular/router'; -import { ThumbnailHeaderComponent } from '../blog/thumbnail-header.component'; -import { fakeTextChapters, posts } from '../data'; -import { PostHeaderComponent } from './post-header.component'; - -@Component({ - selector: 'post', - standalone: true, - imports: [ - ThumbnailHeaderComponent, - NgOptimizedImage, - PostHeaderComponent, - RouterLink, - ], - template: ` -
- - -

{{ post().title }}

- - @for (chapter of fakeTextChapter; track $index) { -

{{ chapter }}

- } -
- `, - host: { - class: 'flex h-full justify-center', - }, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export default class PostComponent { - id = input.required(); - post = computed(() => posts.filter((p) => p.id === this.id())[0]); - - fakeTextChapter = fakeTextChapters; -} diff --git a/apps/angular/view-transition/src/main.ts b/apps/angular/view-transition/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/angular/view-transition/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/angular/view-transition/src/styles.scss b/apps/angular/view-transition/src/styles.scss deleted file mode 100644 index a90f0749c..000000000 --- a/apps/angular/view-transition/src/styles.scss +++ /dev/null @@ -1,4 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - diff --git a/apps/angular/view-transition/tsconfig.app.json b/apps/angular/view-transition/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/angular/view-transition/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/angular/view-transition/tsconfig.json b/apps/angular/view-transition/tsconfig.json deleted file mode 100644 index db0ec0f25..000000000 --- a/apps/angular/view-transition/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json", - }, - { - "path": "./tsconfig.editor.json", - }, - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true, - }, -} diff --git a/apps/nx/static-dynamic-import/.eslintrc.json b/apps/forms/41-control-value-accessor/.eslintrc.json similarity index 100% rename from apps/nx/static-dynamic-import/.eslintrc.json rename to apps/forms/41-control-value-accessor/.eslintrc.json diff --git a/apps/forms/control-value-accessor/README.md b/apps/forms/41-control-value-accessor/README.md similarity index 100% rename from apps/forms/control-value-accessor/README.md rename to apps/forms/41-control-value-accessor/README.md diff --git a/apps/forms/41-control-value-accessor/jest.config.ts b/apps/forms/41-control-value-accessor/jest.config.ts new file mode 100644 index 000000000..ab9c8457e --- /dev/null +++ b/apps/forms/41-control-value-accessor/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'forms-control-value-accessor', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/forms/41-control-value-accessor', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/forms/41-control-value-accessor/project.json b/apps/forms/41-control-value-accessor/project.json new file mode 100644 index 000000000..e9012bd49 --- /dev/null +++ b/apps/forms/41-control-value-accessor/project.json @@ -0,0 +1,81 @@ +{ + "name": "forms-control-value-accessor", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/forms/41-control-value-accessor/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/forms/41-control-value-accessor", + "index": "apps/forms/41-control-value-accessor/src/index.html", + "browser": "apps/forms/41-control-value-accessor/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/forms/41-control-value-accessor/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/forms/41-control-value-accessor/src/favicon.ico", + "apps/forms/41-control-value-accessor/src/assets" + ], + "styles": ["apps/forms/41-control-value-accessor/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "forms-control-value-accessor:build:production" + }, + "development": { + "buildTarget": "forms-control-value-accessor:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "forms-control-value-accessor:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/forms/41-control-value-accessor/src/app/app.component.ts b/apps/forms/41-control-value-accessor/src/app/app.component.ts new file mode 100644 index 000000000..69134b864 --- /dev/null +++ b/apps/forms/41-control-value-accessor/src/app/app.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { FeedbackFormComponent } from './feedback-form/feedback-form.component'; + +@Component({ + imports: [FeedbackFormComponent], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent { + apiCall(event: Record): void { + console.log(event); + } +} diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.html b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.html similarity index 100% rename from apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.html rename to apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.html diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.scss b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.scss similarity index 100% rename from apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.scss rename to apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.scss diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts similarity index 98% rename from apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts rename to apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts index d99700db1..4110d6cf7 100644 --- a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts +++ b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts @@ -8,7 +8,6 @@ import { import { RatingControlComponent } from '../rating-control/rating-control.component'; @Component({ - standalone: true, imports: [RatingControlComponent, ReactiveFormsModule], selector: 'app-feedback-form', templateUrl: 'feedback-form.component.html', diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.html b/apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.html similarity index 100% rename from apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.html rename to apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.html diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.scss b/apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.scss similarity index 100% rename from apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.scss rename to apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.scss diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts b/apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.ts similarity index 96% rename from apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts rename to apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.ts index d6dc31631..5562d1f99 100644 --- a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts +++ b/apps/forms/41-control-value-accessor/src/app/rating-control/rating-control.component.ts @@ -1,7 +1,6 @@ import { Component, EventEmitter, Output } from '@angular/core'; @Component({ - standalone: true, selector: 'app-rating-control', templateUrl: 'rating-control.component.html', styleUrls: ['rating-control.component.scss'], diff --git a/apps/angular/styling/src/assets/.gitkeep b/apps/forms/41-control-value-accessor/src/assets/.gitkeep similarity index 100% rename from apps/angular/styling/src/assets/.gitkeep rename to apps/forms/41-control-value-accessor/src/assets/.gitkeep diff --git a/apps/ngrx/notification/src/favicon.ico b/apps/forms/41-control-value-accessor/src/favicon.ico similarity index 100% rename from apps/ngrx/notification/src/favicon.ico rename to apps/forms/41-control-value-accessor/src/favicon.ico diff --git a/apps/forms/control-value-accessor/src/index.html b/apps/forms/41-control-value-accessor/src/index.html similarity index 100% rename from apps/forms/control-value-accessor/src/index.html rename to apps/forms/41-control-value-accessor/src/index.html diff --git a/apps/forms/41-control-value-accessor/src/main.ts b/apps/forms/41-control-value-accessor/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/forms/41-control-value-accessor/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/performance/default-onpush/src/styles.scss b/apps/forms/41-control-value-accessor/src/styles.scss similarity index 100% rename from apps/performance/default-onpush/src/styles.scss rename to apps/forms/41-control-value-accessor/src/styles.scss diff --git a/apps/forms/41-control-value-accessor/src/test-setup.ts b/apps/forms/41-control-value-accessor/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/forms/41-control-value-accessor/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/performance/memoized/tailwind.config.js b/apps/forms/41-control-value-accessor/tailwind.config.js similarity index 100% rename from apps/performance/memoized/tailwind.config.js rename to apps/forms/41-control-value-accessor/tailwind.config.js diff --git a/apps/forms/41-control-value-accessor/tsconfig.app.json b/apps/forms/41-control-value-accessor/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/forms/41-control-value-accessor/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/simple-animations/tsconfig.editor.json b/apps/forms/41-control-value-accessor/tsconfig.editor.json similarity index 100% rename from apps/angular/simple-animations/tsconfig.editor.json rename to apps/forms/41-control-value-accessor/tsconfig.editor.json diff --git a/apps/forms/41-control-value-accessor/tsconfig.json b/apps/forms/41-control-value-accessor/tsconfig.json new file mode 100644 index 000000000..0b35460df --- /dev/null +++ b/apps/forms/41-control-value-accessor/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/forms/41-control-value-accessor/tsconfig.spec.json b/apps/forms/41-control-value-accessor/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/forms/41-control-value-accessor/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/rxjs/pipe-bug/.eslintrc.json b/apps/forms/48-avoid-losing-form-data/.eslintrc.json similarity index 100% rename from apps/rxjs/pipe-bug/.eslintrc.json rename to apps/forms/48-avoid-losing-form-data/.eslintrc.json diff --git a/apps/forms/48-avoid-losing-form-data/README.md b/apps/forms/48-avoid-losing-form-data/README.md new file mode 100644 index 000000000..1c0e90b35 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/README.md @@ -0,0 +1,11 @@ +# Avoid losing form data + +> author: [Timothy Alcaide](https://github.com/alcaidio) + +### Run Application + +```bash +npx nx serve forms-avoid-losing-form-data +``` + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/forms/48-forms-avoid-losing-form-data/). diff --git a/apps/forms/48-avoid-losing-form-data/project.json b/apps/forms/48-avoid-losing-form-data/project.json new file mode 100644 index 000000000..5bfe98931 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/project.json @@ -0,0 +1,73 @@ +{ + "name": "forms-avoid-losing-form-data", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/forms/48-avoid-losing-form-data/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/forms/48-avoid-losing-form-data", + "index": "apps/forms/48-avoid-losing-form-data/src/index.html", + "browser": "apps/forms/48-avoid-losing-form-data/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/forms/48-avoid-losing-form-data/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/forms/48-avoid-losing-form-data/src/favicon.ico", + "apps/forms/48-avoid-losing-form-data/src/assets" + ], + "styles": [ + "apps/forms/48-avoid-losing-form-data/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "forms-avoid-losing-form-data:build:production" + }, + "development": { + "buildTarget": "forms-avoid-losing-form-data:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "forms-avoid-losing-form-data:build" + } + } + } +} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts new file mode 100644 index 000000000..2b5adc443 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; +import { NavComponent } from './ui/nav.component'; + +@Component({ + imports: [RouterOutlet, NavComponent], + selector: 'app-root', + template: ` +
+ + +
+ +
+
+ `, +}) +export class AppComponent {} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/app.config.ts b/apps/forms/48-avoid-losing-form-data/src/app/app.config.ts new file mode 100644 index 000000000..a7c1007b9 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/app.config.ts @@ -0,0 +1,7 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideRouter, withComponentInputBinding } from '@angular/router'; +import { appRoutes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [provideRouter(appRoutes, withComponentInputBinding())], +}; diff --git a/apps/forms/48-avoid-losing-form-data/src/app/app.routes.ts b/apps/forms/48-avoid-losing-form-data/src/app/app.routes.ts new file mode 100644 index 000000000..84be34b9a --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/app.routes.ts @@ -0,0 +1,29 @@ +import { Route } from '@angular/router'; +import { JoinComponent } from './pages/join.component'; +import { PageComponent } from './pages/page.component'; + +export const appRoutes: Route[] = [ + { + path: '', + pathMatch: 'full', + redirectTo: 'form', + }, + { + path: 'form', + loadComponent: () => JoinComponent, + }, + { + path: 'page-1', + data: { + title: 'Page 1', + }, + loadComponent: () => PageComponent, + }, + { + path: 'page-2', + data: { + title: 'Page 2', + }, + loadComponent: () => PageComponent, + }, +]; diff --git a/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts new file mode 100644 index 000000000..51449a7fb --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts @@ -0,0 +1,15 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { FormComponent } from '../ui/form.component'; + +@Component({ + imports: [FormComponent], + template: ` +
+
+ +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class JoinComponent {} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/pages/page.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/pages/page.component.ts new file mode 100644 index 000000000..a1995eff1 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/pages/page.component.ts @@ -0,0 +1,13 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +@Component({ + template: ` +
+

{{ title() }}

+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PageComponent { + title = input.required(); +} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/ui/dialog.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/ui/dialog.component.ts new file mode 100644 index 000000000..21db4d56f --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/ui/dialog.component.ts @@ -0,0 +1,29 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +// NOTE : this is just the dialog content, you need to implement dialog logic + +@Component({ + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AlertDialogComponent {} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts new file mode 100644 index 000000000..f3190d517 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts @@ -0,0 +1,77 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; + +@Component({ + selector: 'app-form', + imports: [ReactiveFormsModule], + template: ` +
+
+ + +
+ +
+
+ + +
+ +
+ + +
+
+ +
+ + + +
+ +
+ +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FormComponent { + private fb = inject(FormBuilder); + + form = this.fb.nonNullable.group({ + name: ['', { validators: [Validators.required] }], + email: ['', [Validators.required, Validators.email]], // other syntax + phone: '', + message: '', + }); + + onSubmit() { + if (this.form.valid) this.form.reset(); + } +} diff --git a/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts new file mode 100644 index 000000000..269297280 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts @@ -0,0 +1,32 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink, RouterLinkActive } from '@angular/router'; + +@Component({ + selector: 'app-nav', + imports: [RouterLink, RouterLinkActive], + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class NavComponent {} diff --git a/apps/angular/view-transition/src/assets/.gitkeep b/apps/forms/48-avoid-losing-form-data/src/assets/.gitkeep similarity index 100% rename from apps/angular/view-transition/src/assets/.gitkeep rename to apps/forms/48-avoid-losing-form-data/src/assets/.gitkeep diff --git a/apps/nx/static-dynamic-import/src/favicon.ico b/apps/forms/48-avoid-losing-form-data/src/favicon.ico similarity index 100% rename from apps/nx/static-dynamic-import/src/favicon.ico rename to apps/forms/48-avoid-losing-form-data/src/favicon.ico diff --git a/apps/forms/48-avoid-losing-form-data/src/index.html b/apps/forms/48-avoid-losing-form-data/src/index.html new file mode 100644 index 000000000..ed75bb39d --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/index.html @@ -0,0 +1,13 @@ + + + + + form-avoid-losing-form-data + + + + + + + + diff --git a/apps/forms/48-avoid-losing-form-data/src/main.ts b/apps/forms/48-avoid-losing-form-data/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/performance/memoized/src/styles.scss b/apps/forms/48-avoid-losing-form-data/src/styles.scss similarity index 100% rename from apps/performance/memoized/src/styles.scss rename to apps/forms/48-avoid-losing-form-data/src/styles.scss diff --git a/apps/forms/48-avoid-losing-form-data/tailwind.config.js b/apps/forms/48-avoid-losing-form-data/tailwind.config.js new file mode 100644 index 000000000..16f83c7f4 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [require('@tailwindcss/forms')], +}; diff --git a/apps/forms/48-avoid-losing-form-data/tsconfig.app.json b/apps/forms/48-avoid-losing-form-data/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/forms/48-avoid-losing-form-data/tsconfig.editor.json b/apps/forms/48-avoid-losing-form-data/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/forms/48-avoid-losing-form-data/tsconfig.json b/apps/forms/48-avoid-losing-form-data/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/forms/48-avoid-losing-form-data/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/typescript/enums-vs-union-types/.eslintrc.json b/apps/forms/61-simplest-signal-form/.eslintrc.json similarity index 100% rename from apps/typescript/enums-vs-union-types/.eslintrc.json rename to apps/forms/61-simplest-signal-form/.eslintrc.json diff --git a/apps/forms/61-simplest-signal-form/README.md b/apps/forms/61-simplest-signal-form/README.md new file mode 100644 index 000000000..c8a462e5d --- /dev/null +++ b/apps/forms/61-simplest-signal-form/README.md @@ -0,0 +1,13 @@ +# simplest signal form + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve forms-simplest-signal-form +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/forms/61-simplest-signal-form/). diff --git a/apps/forms/61-simplest-signal-form/project.json b/apps/forms/61-simplest-signal-form/project.json new file mode 100644 index 000000000..703fa9975 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/project.json @@ -0,0 +1,81 @@ +{ + "name": "forms-simplest-signal-form", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/forms/61-simplest-signal-form/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular/build:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/forms/61-simplest-signal-form", + "browser": "apps/forms/61-simplest-signal-form/src/main.ts", + "tsConfig": "apps/forms/61-simplest-signal-form/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/forms/61-simplest-signal-form/public" + } + ], + "styles": ["apps/forms/61-simplest-signal-form/src/styles.scss"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "continuous": true, + "executor": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "forms-simplest-signal-form:build:production" + }, + "development": { + "buildTarget": "forms-simplest-signal-form:build:development" + } + }, + "defaultConfiguration": "development" + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@angular/build:unit-test", + "options": { + "runnerConfig": "apps/forms/61-simplest-signal-form/vitest-base.config.ts" + } + }, + "serve-static": { + "continuous": true, + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "forms-simplest-signal-form:build", + "staticFilePath": "dist/apps/forms/61-simplest-signal-form/browser", + "spa": true + } + } + } +} diff --git a/apps/performance/christmas-web-worker/src/favicon.ico b/apps/forms/61-simplest-signal-form/public/favicon.ico similarity index 100% rename from apps/performance/christmas-web-worker/src/favicon.ico rename to apps/forms/61-simplest-signal-form/public/favicon.ico diff --git a/apps/forms/61-simplest-signal-form/src/app/app.component.spec.ts b/apps/forms/61-simplest-signal-form/src/app/app.component.spec.ts new file mode 100644 index 000000000..144c739eb --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/app/app.component.spec.ts @@ -0,0 +1,227 @@ +import { TestBed } from '@angular/core/testing'; +import { page, userEvent } from 'vitest/browser'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + TestBed.createComponent(AppComponent); + }); + + describe('When component is rendered', () => { + it('Then should display the form title', async () => { + const heading = page.getByRole('heading', { name: /simple form/i }); + await expect.element(heading).toBeInTheDocument(); + }); + + it('Then should display all form fields', async () => { + await expect.element(page.getByLabelText('Name *')).toBeInTheDocument(); + await expect + .element(page.getByLabelText(/last name/i)) + .toBeInTheDocument(); + await expect.element(page.getByLabelText(/age/i)).toBeInTheDocument(); + await expect.element(page.getByLabelText(/note/i)).toBeInTheDocument(); + }); + + it('Then submit button should be disabled initially', async () => { + const submitButton = page.getByRole('button', { name: /submit/i }); + await expect.element(submitButton).toBeDisabled(); + }); + }); + + describe('Given valid form data', () => { + describe('When user fills in all required fields', () => { + it('Then submit button should be enabled', async () => { + const nameInput = page.getByLabelText('Name *'); + await nameInput.fill('John'); + + const submitButton = page.getByRole('button', { name: /submit/i }); + await expect.element(submitButton).toBeEnabled(); + }); + }); + + describe('When user submits the form', () => { + it('Then should display submitted data', async () => { + const nameInput = page.getByLabelText('Name *'); + const lastnameInput = page.getByLabelText(/last name/i); + const ageInput = page.getByLabelText(/age/i); + const noteInput = page.getByLabelText(/note/i); + + await nameInput.fill('John'); + await lastnameInput.fill('Doe'); + await ageInput.fill('25'); + await noteInput.fill('Test note'); + + const submitButton = page.getByRole('button', { name: /submit/i }); + await submitButton.click(); + + await expect + .element(page.getByText('Submitted Data:')) + .toBeInTheDocument(); + await expect + .element(page.getByText(/"name": "John"/)) + .toBeInTheDocument(); + await expect + .element(page.getByText(/"lastname": "Doe"/)) + .toBeInTheDocument(); + await expect.element(page.getByText(/"age": 25/)).toBeInTheDocument(); + await expect + .element(page.getByText(/"note": "Test note"/)) + .toBeInTheDocument(); + }); + }); + }); + + describe('Given name field validation', () => { + describe('When name field is empty and touched', () => { + it('Then should display required error', async () => { + const nameInput = page.getByLabelText('Name *'); + await nameInput.click(); + await userEvent.keyboard('{Tab}'); + + await expect + .element(page.getByText('Name is required')) + .toBeInTheDocument(); + }); + + it('Then submit button should be disabled', async () => { + const nameInput = page.getByLabelText('Name *'); + await nameInput.click(); + await userEvent.keyboard('{Tab}'); + + const submitButton = page.getByRole('button', { name: /submit/i }); + await expect.element(submitButton).toBeDisabled(); + }); + }); + }); + + describe('Given age field validation', () => { + describe('When age is less than 1', () => { + it('Then should display min error', async () => { + const nameInput = page.getByLabelText('Name *'); + const ageInput = page.getByLabelText(/age/i); + + await nameInput.fill('John'); + await ageInput.fill('0'); + await userEvent.keyboard('{Tab}'); + + await expect + .element(page.getByText('Age must be at least 1')) + .toBeInTheDocument(); + }); + }); + + describe('When age is greater than 99', () => { + it('Then should display max error', async () => { + const nameInput = page.getByLabelText('Name *'); + const ageInput = page.getByLabelText(/age/i); + + await nameInput.fill('John'); + await ageInput.fill('100'); + await userEvent.keyboard('{Tab}'); + + await expect + .element(page.getByText('Age must be at most 99')) + .toBeInTheDocument(); + }); + }); + + describe('When age is between 1 and 99', () => { + it('Then should not display any error', async () => { + const nameInput = page.getByLabelText('Name *'); + const ageInput = page.getByLabelText(/age/i); + + await nameInput.fill('John'); + await ageInput.fill('50'); + await userEvent.keyboard('{Tab}'); + + await expect + .element(page.getByText(/age must be/i)) + .not.toBeInTheDocument(); + }); + }); + }); + + describe('Given optional fields', () => { + describe('When lastname and note are empty', () => { + it('Then should still allow form submission with valid name', async () => { + const nameInput = page.getByLabelText('Name *'); + await nameInput.fill('John'); + + const submitButton = page.getByRole('button', { name: /submit/i }); + await expect.element(submitButton).toBeEnabled(); + + await submitButton.click(); + + await expect + .element(page.getByText('Submitted Data:')) + .toBeInTheDocument(); + }); + }); + }); + + describe('Given reset functionality', () => { + describe('When user clicks reset button after filling form', () => { + it('Then should clear all form fields', async () => { + const nameInput = page.getByLabelText('Name *'); + const lastnameInput = page.getByLabelText(/last name/i); + const ageInput = page.getByLabelText(/age/i); + const noteInput = page.getByLabelText(/note/i); + + await nameInput.fill('John'); + await lastnameInput.fill('Doe'); + await ageInput.fill('25'); + await noteInput.fill('Test note'); + + const resetButton = page.getByRole('button', { name: /reset/i }); + await resetButton.click(); + + await expect.element(nameInput).toHaveValue(''); + await expect.element(lastnameInput).toHaveValue(''); + await expect.element(ageInput).toHaveValue(null); + await expect.element(noteInput).toHaveValue(''); + }); + + it('Then should hide submitted data if present', async () => { + const nameInput = page.getByLabelText('Name *'); + await nameInput.fill('John'); + + const submitButton = page.getByRole('button', { name: /submit/i }); + await submitButton.click(); + + await expect + .element(page.getByText('Submitted Data:')) + .toBeInTheDocument(); + + const resetButton = page.getByRole('button', { name: /reset/i }); + await resetButton.click(); + + await expect + .element(page.getByText('Submitted Data:')) + .not.toBeInTheDocument(); + }); + }); + }); + + // describe('Given form styling', () => { + // describe('When field has validation error', () => { + // it('Then should display red border on name field', async () => { + // const nameInput = page.getByLabelText(/^Name$/i); + // await nameInput.click(); + // await userEvent.keyboard('{Tab}'); + // + // await expect.element(nameInput).toHaveClass('border-red-500'); + // }); + // + // it('Then should display red border on age field when invalid', async () => { + // const nameInput = page.getByLabelText(/^Name$/i); + // const ageInput = page.getByLabelText(/age/i); + // + // await nameInput.fill('John'); + // await ageInput.fill('0'); + // await page.keyboard.press('Tab'); + // + // await expect.element(ageInput).toHaveClass('border-red-500'); + // }); + // }); + // }); +}); diff --git a/apps/forms/61-simplest-signal-form/src/app/app.component.ts b/apps/forms/61-simplest-signal-form/src/app/app.component.ts new file mode 100644 index 000000000..48edfb268 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/app/app.component.ts @@ -0,0 +1,160 @@ +import { JsonPipe } from '@angular/common'; +import { Component, signal, WritableSignal } from '@angular/core'; +import { + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; + +@Component({ + selector: 'app-root', + imports: [ReactiveFormsModule, JsonPipe], + template: ` +
+
+

Simple Form

+ +
+
+ + + @if (form.controls.name.invalid && !form.controls.name.untouched) { +

Name is required

+ } +
+ +
+ + +
+ +
+ + + @if (form.controls.age.invalid && !form.controls.age.untouched) { +

+ @if (form.controls.age.hasError('min')) { + Age must be at least 1 + } + @if (form.controls.age.hasError('max')) { + Age must be at most 99 + } +

+ } +
+ +
+ + +
+ +
+ + +
+
+ + @if (submittedData()) { +
+

+ Submitted Data: +

+
{{ submittedData() | json }}
+
+ } +
+
+ `, +}) +export class AppComponent { + form = new FormGroup({ + name: new FormControl('', { + validators: Validators.required, + nonNullable: true, + }), + lastname: new FormControl('', { nonNullable: true }), + age: new FormControl(null, [ + Validators.min(1), + Validators.max(99), + ]), + note: new FormControl('', { nonNullable: true }), + }); + + submittedData: WritableSignal<{ + name: string; + lastname: string; + age: number | null; + note: string; + } | null> = signal(null); + + onSubmit(): void { + if (this.form.valid) { + this.submittedData.set(this.form.getRawValue()); + console.log('Form submitted:', this.submittedData); + } + } + + onReset(): void { + this.form.reset(); + this.submittedData.set(null); + } +} diff --git a/apps/forms/61-simplest-signal-form/src/app/app.config.ts b/apps/forms/61-simplest-signal-form/src/app/app.config.ts new file mode 100644 index 000000000..50d39c4f8 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/app/app.config.ts @@ -0,0 +1,8 @@ +import { + ApplicationConfig, + provideBrowserGlobalErrorListeners, +} from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideBrowserGlobalErrorListeners()], +}; diff --git a/apps/forms/61-simplest-signal-form/src/index.html b/apps/forms/61-simplest-signal-form/src/index.html new file mode 100644 index 000000000..e877ac41c --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/index.html @@ -0,0 +1,13 @@ + + + + + forms-simplest-signal-form + + + + + + + + diff --git a/apps/angular/router-input/src/main.ts b/apps/forms/61-simplest-signal-form/src/main.ts similarity index 100% rename from apps/angular/router-input/src/main.ts rename to apps/forms/61-simplest-signal-form/src/main.ts diff --git a/apps/performance/ngfor-biglist/src/styles.scss b/apps/forms/61-simplest-signal-form/src/styles.scss similarity index 100% rename from apps/performance/ngfor-biglist/src/styles.scss rename to apps/forms/61-simplest-signal-form/src/styles.scss diff --git a/apps/forms/61-simplest-signal-form/src/test-setup/no-teardown.ts b/apps/forms/61-simplest-signal-form/src/test-setup/no-teardown.ts new file mode 100644 index 000000000..655736368 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/test-setup/no-teardown.ts @@ -0,0 +1,25 @@ +import { getTestBed } from '@angular/core/testing'; +import { + BrowserTestingModule, + platformBrowserTesting, +} from '@angular/platform-browser/testing'; +import { beforeEach } from 'vitest'; + +/** + * @see https://github.com/angular/angular-cli/issues/31733 + */ +const symbol = Symbol.for('@angular-challenge/testbed-setup'); +const g = globalThis as unknown as { [symbol]: boolean }; + +if (!g[symbol]) { + g[symbol] = true; + + getTestBed().resetTestEnvironment(); + getTestBed().initTestEnvironment( + BrowserTestingModule, + platformBrowserTesting(), + { teardown: { destroyAfterEach: false } }, + ); +} + +beforeEach(() => getTestBed().resetTestingModule()); diff --git a/apps/performance/ngfor-biglist/tailwind.config.js b/apps/forms/61-simplest-signal-form/tailwind.config.js similarity index 100% rename from apps/performance/ngfor-biglist/tailwind.config.js rename to apps/forms/61-simplest-signal-form/tailwind.config.js diff --git a/apps/forms/61-simplest-signal-form/tsconfig.app.json b/apps/forms/61-simplest-signal-form/tsconfig.app.json new file mode 100644 index 000000000..ba6acbecd --- /dev/null +++ b/apps/forms/61-simplest-signal-form/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/apps/forms/61-simplest-signal-form/tsconfig.json b/apps/forms/61-simplest-signal-form/tsconfig.json new file mode 100644 index 000000000..8e74c6bc1 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "isolatedModules": true, + "target": "es2022", + "moduleResolution": "bundler", + "emitDecoratorMetadata": false, + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/apps/forms/61-simplest-signal-form/tsconfig.spec.json b/apps/forms/61-simplest-signal-form/tsconfig.spec.json new file mode 100644 index 000000000..55718726e --- /dev/null +++ b/apps/forms/61-simplest-signal-form/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts", "src/**/*.d.ts"] +} diff --git a/apps/forms/61-simplest-signal-form/vitest-base.config.ts b/apps/forms/61-simplest-signal-form/vitest-base.config.ts new file mode 100644 index 000000000..1068861c8 --- /dev/null +++ b/apps/forms/61-simplest-signal-form/vitest-base.config.ts @@ -0,0 +1,18 @@ +import { playwright } from '@vitest/browser-playwright'; +import { defineConfig } from 'vitest/config'; + +const teardown = process.env['TEARDOWN'] !== 'false'; + +export default defineConfig({ + test: { + setupFiles: [ + 'apps/forms/61-simplest-signal-form/src/test-setup/no-teardown.ts', + ], + testTimeout: 3_000, + browser: { + enabled: true, + provider: playwright(), + instances: [{ browser: 'chromium' }], + }, + }, +}); diff --git a/apps/forms/control-value-accessor/jest.config.ts b/apps/forms/control-value-accessor/jest.config.ts deleted file mode 100644 index 4af08e195..000000000 --- a/apps/forms/control-value-accessor/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'forms-control-value-accessor', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/forms/control-value-accessor', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/forms/control-value-accessor/project.json b/apps/forms/control-value-accessor/project.json deleted file mode 100644 index 70b8025c2..000000000 --- a/apps/forms/control-value-accessor/project.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "forms-control-value-accessor", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/forms/control-value-accessor/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/forms/control-value-accessor", - "index": "apps/forms/control-value-accessor/src/index.html", - "browser": "apps/forms/control-value-accessor/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/forms/control-value-accessor/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/forms/control-value-accessor/src/favicon.ico", - "apps/forms/control-value-accessor/src/assets" - ], - "styles": ["apps/forms/control-value-accessor/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "forms-control-value-accessor:build:production" - }, - "development": { - "buildTarget": "forms-control-value-accessor:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "forms-control-value-accessor:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/forms/control-value-accessor/jest.config.ts" - } - } - } -} diff --git a/apps/forms/control-value-accessor/src/app/app.component.ts b/apps/forms/control-value-accessor/src/app/app.component.ts deleted file mode 100644 index f56b5d7d9..000000000 --- a/apps/forms/control-value-accessor/src/app/app.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from '@angular/core'; -import { FeedbackFormComponent } from './feedback-form/feedback-form.component'; - -@Component({ - standalone: true, - imports: [FeedbackFormComponent], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent { - apiCall(event: Record): void { - console.log(event); - } -} diff --git a/apps/forms/control-value-accessor/src/main.ts b/apps/forms/control-value-accessor/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/forms/control-value-accessor/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/forms/control-value-accessor/src/test-setup.ts b/apps/forms/control-value-accessor/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/forms/control-value-accessor/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/forms/control-value-accessor/tsconfig.app.json b/apps/forms/control-value-accessor/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/forms/control-value-accessor/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/forms/control-value-accessor/tsconfig.json b/apps/forms/control-value-accessor/tsconfig.json deleted file mode 100644 index 25ca437b4..000000000 --- a/apps/forms/control-value-accessor/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/forms/control-value-accessor/tsconfig.spec.json b/apps/forms/control-value-accessor/tsconfig.spec.json deleted file mode 100644 index 1a4817a7d..000000000 --- a/apps/forms/control-value-accessor/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/ngrx/effect-selector/README.md b/apps/ngrx/effect-selector/README.md deleted file mode 100644 index b12a5341e..000000000 --- a/apps/ngrx/effect-selector/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Effect vs Selector - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve ngrx-effect-selector -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/ngrx/2-effect-selector/). diff --git a/apps/ngrx/effect-selector/jest.config.ts b/apps/ngrx/effect-selector/jest.config.ts deleted file mode 100644 index 86ed38d00..000000000 --- a/apps/ngrx/effect-selector/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'ngrx-effect-selector', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/apps/ngrx/effect-selector', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/ngrx/effect-selector/project.json b/apps/ngrx/effect-selector/project.json deleted file mode 100644 index 8cd2d729c..000000000 --- a/apps/ngrx/effect-selector/project.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "name": "ngrx-effect-selector", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/ngrx/effect-selector/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/ngrx/effect-selector", - "index": "apps/ngrx/effect-selector/src/index.html", - "main": "apps/ngrx/effect-selector/src/main.ts", - "polyfills": "apps/ngrx/effect-selector/src/polyfills.ts", - "tsConfig": "apps/ngrx/effect-selector/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/ngrx/effect-selector/src/favicon.ico", - "apps/ngrx/effect-selector/src/assets" - ], - "styles": ["apps/ngrx/effect-selector/src/styles.scss"], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "ngrx-effect-selector:build:production" - }, - "development": { - "buildTarget": "ngrx-effect-selector:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "ngrx-effect-selector:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/ngrx/effect-selector/jest.config.ts" - } - } - }, - "tags": [] -} diff --git a/apps/ngrx/effect-selector/src/app/app.component.ts b/apps/ngrx/effect-selector/src/app/app.component.ts deleted file mode 100644 index 1e4836644..000000000 --- a/apps/ngrx/effect-selector/src/app/app.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { AsyncPipe, NgFor } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - OnInit, - inject, -} from '@angular/core'; -import { Store } from '@ngrx/store'; -import { loadActivities } from './store/activity/activity.actions'; -import { ActivityType } from './store/activity/activity.model'; -import { selectActivities } from './store/activity/activity.selectors'; -import { loadStatuses } from './store/status/status.actions'; -import { selectAllTeachersByActivityType } from './store/status/status.selectors'; -import { loadUsers } from './store/user/user.actions'; - -@Component({ - selector: 'app-root', - standalone: true, - imports: [NgFor, AsyncPipe], - template: ` -

Activity Board

-
-
-

Activity Name: {{ activity.name }}

-

Main teacher: {{ activity.teacher.name }}

- All teachers available for : {{ activity.type }} are -
    -
  • - {{ teacher.name }} -
  • -
-
-
- `, - styles: [ - ` - section { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 2px; - } - - .card { - display: flex; - flex-direction: column; - border: solid; - border-width: 1px; - border-color: black; - padding: 2px; - } - `, - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent implements OnInit { - private store = inject(Store); - - activities$ = this.store.select(selectActivities); - - ngOnInit(): void { - this.store.dispatch(loadActivities()); - this.store.dispatch(loadUsers()); - this.store.dispatch(loadStatuses()); - } - - getAllTeachersForActivityType$ = (type: ActivityType) => - this.store.select(selectAllTeachersByActivityType(type)); -} diff --git a/apps/ngrx/effect-selector/src/app/app.config.ts b/apps/ngrx/effect-selector/src/app/app.config.ts deleted file mode 100644 index d59c436ed..000000000 --- a/apps/ngrx/effect-selector/src/app/app.config.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ApplicationConfig } from '@angular/core'; -import { provideEffects } from '@ngrx/effects'; -import { provideStore } from '@ngrx/store'; -import { ActivityEffects } from './store/activity/activity.effects'; -import { - activityFeatureKey, - activityReducer, -} from './store/activity/activity.reducer'; -import { StatusEffects } from './store/status/status.effects'; -import { UserEffects } from './store/user/user.effects'; - -import { statusFeatureKey, statusReducer } from './store/status/status.reducer'; - -import { userFeatureKey, userReducer } from './store/user/user.reducer'; - -const reducers = { - [statusFeatureKey]: statusReducer, - [activityFeatureKey]: activityReducer, - [userFeatureKey]: userReducer, -}; - -export const appConfig: ApplicationConfig = { - providers: [ - provideStore(reducers), - provideEffects([ActivityEffects, UserEffects, StatusEffects]), - ], -}; diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts deleted file mode 100644 index c8affff54..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createAction, props } from '@ngrx/store'; -import { Activity } from './activity.model'; - -export const loadActivities = createAction('[Activity Effect] Load Activities'); - -export const loadActivitiesSuccess = createAction( - '[Activity Effect] Load Activities Success', - props<{ activities: Activity[] }>(), -); - -export const loadActivitiesFailure = createAction( - '[Activity Effect] Load Activities Failure', - props<{ error: unknown }>(), -); diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts deleted file mode 100644 index 88f8b2317..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { of } from 'rxjs'; -import { catchError, concatMap, map } from 'rxjs/operators'; -import * as ActivityActions from './activity.actions'; -import { ActivityService } from './activity.service'; - -@Injectable() -export class ActivityEffects { - loadActivities$ = createEffect(() => { - return this.actions$.pipe( - ofType(ActivityActions.loadActivities), - concatMap(() => - this.ActivityService.fetchActivities().pipe( - map((activities) => - ActivityActions.loadActivitiesSuccess({ activities }), - ), - catchError((error) => - of(ActivityActions.loadActivitiesFailure({ error })), - ), - ), - ), - ); - }); - - constructor( - private actions$: Actions, - private ActivityService: ActivityService, - ) {} -} diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.model.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.model.ts deleted file mode 100644 index 75f188132..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.model.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - incrementalNumber, - rand, - randFirstName, - randText, -} from '@ngneat/falso'; - -export const activityType = [ - 'Sport', - 'Sciences', - 'History', - 'Maths', - 'Physics', -] as const; -export type ActivityType = (typeof activityType)[number]; - -export interface Person { - id: number; - name: string; -} - -export interface Activity { - id: number; - name: string; - type: ActivityType; - teacher: Person; -} - -const factoryPerson = incrementalNumber(); - -export const randPerson = () => ({ - id: factoryPerson(), - name: randFirstName(), -}); - -const factoryActivity = incrementalNumber(); - -export const randActivity = (): Activity => ({ - id: factoryActivity(), - name: randText(), - type: rand(activityType), - teacher: randPerson(), -}); - -export const activities: Activity[] = [ - randActivity(), - randActivity(), - randActivity(), - randActivity(), - randActivity(), - randActivity(), - randActivity(), - randActivity(), - randActivity(), -]; diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts deleted file mode 100644 index b7285e8f6..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createReducer, on } from '@ngrx/store'; -import * as ActivityActions from './activity.actions'; -import { Activity } from './activity.model'; - -export const activityFeatureKey = 'Activity'; - -export interface ActivityState { - activities: Activity[]; -} - -export const initialState: ActivityState = { - activities: [], -}; - -export const activityReducer = createReducer( - initialState, - on(ActivityActions.loadActivitiesSuccess, (state, { activities }) => ({ - ...state, - activities, - })), - on(ActivityActions.loadActivitiesFailure, (state) => ({ - state, - activities: [], - })), -); diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts deleted file mode 100644 index 6c6a25a65..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { ActivityState, activityFeatureKey } from './activity.reducer'; - -export const selectActivityState = - createFeatureSelector(activityFeatureKey); - -export const selectActivities = createSelector( - selectActivityState, - (state) => state.activities, -); diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.service.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.service.ts deleted file mode 100644 index 07aa8f8ad..000000000 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Injectable } from '@angular/core'; -import { map, timer } from 'rxjs'; -import { activities } from './activity.model'; - -@Injectable({ - providedIn: 'root', -}) -export class ActivityService { - fetchActivities = () => timer(500).pipe(map(() => activities)); -} diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts b/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts deleted file mode 100644 index 8fc2ddc49..000000000 --- a/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createAction, props } from '@ngrx/store'; -import { Status } from './status.model'; - -export const loadStatuses = createAction('[Status] Load Statuses'); - -export const loadStatusesSuccess = createAction( - '[Status] Load Statuses Success', - props<{ statuses: Status[] }>(), -); diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts b/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts deleted file mode 100644 index 997eb0c1f..000000000 --- a/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { Store } from '@ngrx/store'; -import { combineLatest, concatMap, map } from 'rxjs'; -import { selectActivities } from '../activity/activity.selectors'; -import { selectUser } from '../user/user.selectors'; -import * as StatusActions from './status.actions'; -import { Status } from './status.model'; - -@Injectable() -export class StatusEffects { - loadStatuses$ = createEffect(() => { - return this.actions$.pipe( - ofType(StatusActions.loadStatuses), - concatMap(() => - combineLatest([ - this.store.select(selectUser), - this.store.select(selectActivities), - ]).pipe( - map(([user, activities]): Status[] => { - if (user?.isAdmin) { - return activities.reduce( - (status: Status[], activity): Status[] => { - const index = status.findIndex( - (s) => s.name === activity.type, - ); - if (index === -1) { - return [ - ...status, - { name: activity.type, teachers: [activity.teacher] }, - ]; - } else { - status[index].teachers.push(activity.teacher); - return status; - } - }, - [], - ); - } - return []; - }), - map((statuses) => StatusActions.loadStatusesSuccess({ statuses })), - ), - ), - ); - }); - - constructor( - private actions$: Actions, - private store: Store, - ) {} -} diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.model.ts b/apps/ngrx/effect-selector/src/app/store/status/status.model.ts deleted file mode 100644 index 07733834a..000000000 --- a/apps/ngrx/effect-selector/src/app/store/status/status.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ActivityType, Person } from '../activity/activity.model'; - -export interface Status { - name: ActivityType; - teachers: Person[]; -} diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts b/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts deleted file mode 100644 index b91cbe2fb..000000000 --- a/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { createReducer, on } from '@ngrx/store'; -import { ActivityType, Person } from '../activity/activity.model'; -import * as StatusActions from './status.actions'; -import { Status } from './status.model'; - -export const statusFeatureKey = 'status'; - -export interface StatusState { - statuses: Status[]; - teachersMap: Map; -} - -export const initialState: StatusState = { - statuses: [], - teachersMap: new Map(), -}; - -export const statusReducer = createReducer( - initialState, - on(StatusActions.loadStatusesSuccess, (state, { statuses }): StatusState => { - const map = new Map(); - statuses.forEach((s) => map.set(s.name, s.teachers)); - return { - ...state, - statuses, - teachersMap: map, - }; - }), -); diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts b/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts deleted file mode 100644 index 80ed059a6..000000000 --- a/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { ActivityType } from '../activity/activity.model'; -import { StatusState, statusFeatureKey } from './status.reducer'; - -export const selectStatusState = - createFeatureSelector(statusFeatureKey); - -export const selectStatuses = createSelector( - selectStatusState, - (state) => state.statuses, -); - -export const selectAllTeachersByActivityType = (name: ActivityType) => - createSelector( - selectStatusState, - (state) => state.teachersMap.get(name) ?? [], - ); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts b/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts deleted file mode 100644 index a73147dce..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createAction, props } from '@ngrx/store'; -import { User } from './user.model'; - -export const loadUsers = createAction('[User] Load Users'); - -export const loadUsersSuccess = createAction( - '[User] Load Users Success', - props<{ user: User }>(), -); - -export const loadUsersFailure = createAction( - '[User] Load Users Failure', - props<{ error: unknown }>(), -); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts b/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts deleted file mode 100644 index fff3f6f6c..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { of } from 'rxjs'; -import { catchError, concatMap, map } from 'rxjs/operators'; -import * as UserActions from './user.actions'; -import { UserService } from './user.service'; - -@Injectable() -export class UserEffects { - loadUsers$ = createEffect(() => { - return this.actions$.pipe( - ofType(UserActions.loadUsers), - concatMap(() => - this.userService.fetchUser().pipe( - map((user) => UserActions.loadUsersSuccess({ user })), - catchError((error) => of(UserActions.loadUsersFailure({ error }))), - ), - ), - ); - }); - - constructor( - private actions$: Actions, - private userService: UserService, - ) {} -} diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.model.ts b/apps/ngrx/effect-selector/src/app/store/user/user.model.ts deleted file mode 100644 index d7692041c..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.model.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { randFirstName, randLastName, randText } from '@ngneat/falso'; - -export interface User { - firstname: string; - lastname: string; - isAdmin: boolean; - apiKey: string; -} - -export const user: User = { - firstname: randFirstName(), - lastname: randLastName(), - isAdmin: true, - apiKey: randText(), -}; diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts b/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts deleted file mode 100644 index 3f4768c18..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createReducer, on } from '@ngrx/store'; -import * as UserActions from './user.actions'; -import { User } from './user.model'; - -export const userFeatureKey = 'user'; - -export interface UserState { - user?: User; -} - -export const initialState: UserState = { - user: undefined, -}; - -export const userReducer = createReducer( - initialState, - on(UserActions.loadUsersSuccess, (state, { user }) => ({ ...state, user })), - on(UserActions.loadUsersFailure, (state) => ({ ...state, user: undefined })), -); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts b/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts deleted file mode 100644 index 7970b0dfe..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { UserState, userFeatureKey } from './user.reducer'; - -export const selectUserState = createFeatureSelector(userFeatureKey); - -export const selectUser = createSelector( - selectUserState, - (state) => state.user, -); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.service.ts b/apps/ngrx/effect-selector/src/app/store/user/user.service.ts deleted file mode 100644 index a407b020a..000000000 --- a/apps/ngrx/effect-selector/src/app/store/user/user.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Injectable } from '@angular/core'; -import { map, timer } from 'rxjs'; -import { user } from './user.model'; - -@Injectable({ - providedIn: 'root', -}) -export class UserService { - fetchUser = () => timer(500).pipe(map(() => user)); -} diff --git a/apps/ngrx/effect-selector/src/index.html b/apps/ngrx/effect-selector/src/index.html deleted file mode 100644 index 21d573669..000000000 --- a/apps/ngrx/effect-selector/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Ngrx1 - - - - - - - - diff --git a/apps/ngrx/effect-selector/src/main.ts b/apps/ngrx/effect-selector/src/main.ts deleted file mode 100644 index 31c2a3482..000000000 --- a/apps/ngrx/effect-selector/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig); diff --git a/apps/ngrx/effect-selector/src/polyfills.ts b/apps/ngrx/effect-selector/src/polyfills.ts deleted file mode 100644 index e4555ed11..000000000 --- a/apps/ngrx/effect-selector/src/polyfills.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes recent versions of Safari, Chrome (including - * Opera), Edge on the desktop, and iOS and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/apps/ngrx/effect-selector/src/test-setup.ts b/apps/ngrx/effect-selector/src/test-setup.ts deleted file mode 100644 index 1100b3e8a..000000000 --- a/apps/ngrx/effect-selector/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular/setup-jest'; diff --git a/apps/ngrx/effect-selector/tsconfig.app.json b/apps/ngrx/effect-selector/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/ngrx/effect-selector/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/ngrx/effect-selector/tsconfig.editor.json b/apps/ngrx/effect-selector/tsconfig.editor.json deleted file mode 100644 index 20c4afdbf..000000000 --- a/apps/ngrx/effect-selector/tsconfig.editor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["**/*.ts"], - "compilerOptions": { - "types": ["jest", "node"] - } -} diff --git a/apps/ngrx/effect-selector/tsconfig.json b/apps/ngrx/effect-selector/tsconfig.json deleted file mode 100644 index 52eb4f718..000000000 --- a/apps/ngrx/effect-selector/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/ngrx/effect-selector/tsconfig.spec.json b/apps/ngrx/effect-selector/tsconfig.spec.json deleted file mode 100644 index 7aa46d88c..000000000 --- a/apps/ngrx/effect-selector/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/apps/ngrx/notification/README.md b/apps/ngrx/notification/README.md deleted file mode 100644 index 36acdab46..000000000 --- a/apps/ngrx/notification/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Power of Effect - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve ngrx-notification -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/ngrx/7-power-effect/). diff --git a/apps/ngrx/notification/project.json b/apps/ngrx/notification/project.json deleted file mode 100644 index 3f8a85179..000000000 --- a/apps/ngrx/notification/project.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "ngrx-notification", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/ngrx/notification/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/ngrx/notification", - "index": "apps/ngrx/notification/src/index.html", - "main": "apps/ngrx/notification/src/main.ts", - "polyfills": "apps/ngrx/notification/src/polyfills.ts", - "tsConfig": "apps/ngrx/notification/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/ngrx/notification/src/favicon.ico", - "apps/ngrx/notification/src/assets" - ], - "styles": [ - "apps/ngrx/notification/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "ngrx-notification:build:production" - }, - "development": { - "buildTarget": "ngrx-notification:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "ngrx-notification:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/ngrx/notification/src/app/app.actions.ts b/apps/ngrx/notification/src/app/app.actions.ts deleted file mode 100644 index 3dcba8134..000000000 --- a/apps/ngrx/notification/src/app/app.actions.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createActionGroup, emptyProps } from '@ngrx/store'; - -// This is the global actions. -export const appActions = createActionGroup({ - source: 'App Component', - events: { - 'Init App': emptyProps(), - }, -}); diff --git a/apps/ngrx/notification/src/app/app.component.ts b/apps/ngrx/notification/src/app/app.component.ts deleted file mode 100644 index dc14376ac..000000000 --- a/apps/ngrx/notification/src/app/app.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, inject, OnInit } from '@angular/core'; -import { RouterLink, RouterOutlet } from '@angular/router'; -import { Store } from '@ngrx/store'; -import { appActions } from './app.actions'; - -@Component({ - standalone: true, - imports: [RouterOutlet, RouterLink], - selector: 'app-root', - template: ` - - - - `, - styles: [ - ` - :host { - display: flex; - flex-direction: column; - gap: 20px; - - nav { - display: flex; - gap: 20px; - } - } - `, - ], -}) -export class AppComponent implements OnInit { - private store = inject(Store); - - ngOnInit(): void { - this.store.dispatch(appActions.initApp()); - } -} diff --git a/apps/ngrx/notification/src/app/app.config.ts b/apps/ngrx/notification/src/app/app.config.ts deleted file mode 100644 index b36822344..000000000 --- a/apps/ngrx/notification/src/app/app.config.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { FakeBackendService } from '@angular-challenges/ngrx-notification/backend'; -import { APP_INITIALIZER, ApplicationConfig, inject } from '@angular/core'; -import { provideAnimations } from '@angular/platform-browser/animations'; -import { provideRouter } from '@angular/router'; -import { provideEffects } from '@ngrx/effects'; -import { provideStore } from '@ngrx/store'; -import { NotificationService } from './data-access/notification.service'; -import { ROUTES } from './routes'; -import { StudentEffects } from './student/store/student.effects'; -import { - studentReducer, - studentsFeatureKey, -} from './student/store/student.reducer'; -import { TeacherEffects } from './teacher/store/teacher.effects'; -import { - teacherReducer, - teachersFeatureKey, -} from './teacher/store/teacher.reducer'; - -const REDUCERS = { - [teachersFeatureKey]: teacherReducer, - [studentsFeatureKey]: studentReducer, -}; - -export const appConfig: ApplicationConfig = { - providers: [ - provideStore(REDUCERS), - provideEffects([TeacherEffects, StudentEffects]), - provideRouter(ROUTES), - { - provide: APP_INITIALIZER, - multi: true, - useFactory: () => { - const service = inject(FakeBackendService); - return () => service.start(); - }, - }, - { - provide: APP_INITIALIZER, - multi: true, - useFactory: () => { - const service = inject(NotificationService); - return () => service.init(); - }, - }, - provideAnimations(), - ], -}; diff --git a/apps/ngrx/notification/src/app/data-access/http.service.ts b/apps/ngrx/notification/src/app/data-access/http.service.ts deleted file mode 100644 index b5a59aab0..000000000 --- a/apps/ngrx/notification/src/app/data-access/http.service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { FakeBackendService } from '@angular-challenges/ngrx-notification/backend'; -import { inject, Injectable } from '@angular/core'; -import { take } from 'rxjs'; - -@Injectable({ providedIn: 'root' }) -export class HttpService { - private fakeBackend = inject(FakeBackendService); - - getAllTeachers = () => this.fakeBackend.getAllTeachers().pipe(take(1)); - - getAllStudents = () => this.fakeBackend.getAllStudents().pipe(take(1)); - - getAllSchools = () => this.fakeBackend.getAllSchools().pipe(take(1)); -} diff --git a/apps/ngrx/notification/src/app/data-access/notification.service.ts b/apps/ngrx/notification/src/app/data-access/notification.service.ts deleted file mode 100644 index b11614054..000000000 --- a/apps/ngrx/notification/src/app/data-access/notification.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { PushService } from '@angular-challenges/ngrx-notification/backend'; -import { - isSchool, - isStudent, - isTeacher, - Push, -} from '@angular-challenges/ngrx-notification/model'; -import { inject, Injectable } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { filter } from 'rxjs'; -import { studentActions } from '../student/store/student.actions'; -import { teacherActions } from '../teacher/store/teacher.actions'; - -@Injectable({ providedIn: 'root' }) -export class NotificationService { - private pushService = inject(PushService); - private store = inject(Store); - - init() { - this.pushService.notification$ - .pipe(filter(Boolean)) - .subscribe((notification: Push) => { - if (isTeacher(notification)) { - this.store.dispatch( - teacherActions.addOneTeacher({ teacher: notification }), - ); - } - if (isStudent(notification)) { - this.store.dispatch( - studentActions.addOneStudent({ student: notification }), - ); - } - if (isSchool(notification)) { - // SchoolStore is a ComponentStore. We can't dispatch a school action here. - // We are stuck. We must have done something wrong and need to refactor... - } - }); - } -} diff --git a/apps/ngrx/notification/src/app/routes.ts b/apps/ngrx/notification/src/app/routes.ts deleted file mode 100644 index 7db44a4dc..000000000 --- a/apps/ngrx/notification/src/app/routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Route } from '@angular/router'; -import { TeacherComponent } from './teacher/teacher.component'; - -export const ROUTES: Route[] = [ - { path: '', pathMatch: 'full', redirectTo: 'teacher' }, - { - path: 'teacher', - component: TeacherComponent, - }, - { - path: 'student', - loadComponent: () => - import('./student/student.component').then((m) => m.StudentComponent), - }, - { - path: 'school', - loadComponent: () => - import('./school/school.component').then((m) => m.SchoolComponent), - }, -]; diff --git a/apps/ngrx/notification/src/app/school/school.component.ts b/apps/ngrx/notification/src/app/school/school.component.ts deleted file mode 100644 index af58af9c1..000000000 --- a/apps/ngrx/notification/src/app/school/school.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { AsyncPipe, NgFor } from '@angular/common'; -import { Component, inject } from '@angular/core'; -import { provideComponentStore } from '@ngrx/component-store'; -import { SchoolStore } from './school.store'; - -@Component({ - standalone: true, - imports: [NgFor, AsyncPipe], - providers: [provideComponentStore(SchoolStore)], - selector: 'school', - template: ` -

SCHOOL

-
- {{ school.name }} - {{ school.version }} -
- `, - styles: [ - ` - :host { - display: block; - width: fit-content; - height: fit-content; - border: 1px solid red; - padding: 4px; - } - `, - ], -}) -export class SchoolComponent { - private store = inject(SchoolStore); - school$ = this.store.schools$; -} diff --git a/apps/ngrx/notification/src/app/school/school.store.ts b/apps/ngrx/notification/src/app/school/school.store.ts deleted file mode 100644 index 0fd31fa6d..000000000 --- a/apps/ngrx/notification/src/app/school/school.store.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { School } from '@angular-challenges/ngrx-notification/model'; -import { Injectable } from '@angular/core'; -import { - ComponentStore, - OnStoreInit, - tapResponse, -} from '@ngrx/component-store'; -import { pipe, switchMap } from 'rxjs'; -import { HttpService } from '../data-access/http.service'; - -@Injectable() -export class SchoolStore - extends ComponentStore<{ schools: School[] }> - implements OnStoreInit -{ - readonly schools$ = this.select((state) => state.schools); - - constructor(private httpService: HttpService) { - super({ schools: [] }); - } - - addSchool = this.updater((state, school: School) => ({ - ...state, - schools: [...state.schools, school], - })); - - updateSchool = this.updater((state, school: School) => ({ - ...state, - schools: state.schools.map((t) => (t.id === school.id ? school : t)), - })); - - private readonly loadSchools = this.effect( - pipe( - switchMap(() => - this.httpService.getAllSchools().pipe( - tapResponse( - (schools) => this.patchState({ schools }), - (_) => _, // not handling the error - ), - ), - ), - ), - ); - - ngrxOnStoreInit() { - this.loadSchools(); - } -} diff --git a/apps/ngrx/notification/src/app/student/store/student.actions.ts b/apps/ngrx/notification/src/app/student/store/student.actions.ts deleted file mode 100644 index 52eda8ee0..000000000 --- a/apps/ngrx/notification/src/app/student/store/student.actions.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Student } from '@angular-challenges/ngrx-notification/model'; -import { createActionGroup, props } from '@ngrx/store'; - -export const studentActions = createActionGroup({ - source: 'Student API', - events: { - 'Add One Student': props<{ student: Student }>(), - 'Add All Students': props<{ students: Student[] }>(), - }, -}); diff --git a/apps/ngrx/notification/src/app/student/store/student.effects.ts b/apps/ngrx/notification/src/app/student/store/student.effects.ts deleted file mode 100644 index b741bd21d..000000000 --- a/apps/ngrx/notification/src/app/student/store/student.effects.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { inject, Injectable } from '@angular/core'; -import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { map, switchMap } from 'rxjs'; -import { appActions } from '../../app.actions'; -import { HttpService } from '../../data-access/http.service'; -import { studentActions } from './student.actions'; - -@Injectable() -export class StudentEffects { - private actions$ = inject(Actions); - private httpService = inject(HttpService); - - loadStudents$ = createEffect(() => - this.actions$.pipe( - ofType(appActions.initApp), - switchMap(() => - this.httpService - .getAllStudents() - .pipe(map((students) => studentActions.addAllStudents({ students }))), - ), - ), - ); -} diff --git a/apps/ngrx/notification/src/app/student/store/student.reducer.ts b/apps/ngrx/notification/src/app/student/store/student.reducer.ts deleted file mode 100644 index 0b02cd322..000000000 --- a/apps/ngrx/notification/src/app/student/store/student.reducer.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Student } from '@angular-challenges/ngrx-notification/model'; -import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity'; -import { createReducer, on } from '@ngrx/store'; -import { studentActions } from './student.actions'; - -export const studentsFeatureKey = 'students'; - -export type StudentState = EntityState; - -export const studentAdapter: EntityAdapter = - createEntityAdapter(); - -export const studentReducer = createReducer( - studentAdapter.getInitialState(), - on(studentActions.addOneStudent, (state, { student }) => - studentAdapter.upsertOne(student, state), - ), - on(studentActions.addAllStudents, (state, { students }) => - studentAdapter.setAll(students, state), - ), -); - -export const { selectIds, selectEntities, selectAll, selectTotal } = - studentAdapter.getSelectors(); diff --git a/apps/ngrx/notification/src/app/student/store/student.selectors.ts b/apps/ngrx/notification/src/app/student/store/student.selectors.ts deleted file mode 100644 index b041ff420..000000000 --- a/apps/ngrx/notification/src/app/student/store/student.selectors.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { - StudentState, - studentAdapter, - studentsFeatureKey, -} from './student.reducer'; - -const selectStudentState = - createFeatureSelector(studentsFeatureKey); - -export const { selectAll } = studentAdapter.getSelectors(); - -const selectStudents = createSelector(selectStudentState, selectAll); - -export const StudentSelectors = { - selectStudents, -}; diff --git a/apps/ngrx/notification/src/app/student/student.component.ts b/apps/ngrx/notification/src/app/student/student.component.ts deleted file mode 100644 index bbc45bfd7..000000000 --- a/apps/ngrx/notification/src/app/student/student.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { AsyncPipe, NgFor } from '@angular/common'; -import { Component, inject } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { StudentSelectors } from './store/student.selectors'; - -@Component({ - standalone: true, - imports: [NgFor, AsyncPipe], - selector: 'student', - template: ` -

STUDENTS

-
- {{ student.firstname }} {{ student.lastname }} - {{ student.version }} -
- `, - styles: [ - ` - :host { - display: block; - width: fit-content; - height: fit-content; - border: 1px solid red; - padding: 4px; - } - `, - ], -}) -export class StudentComponent { - private store = inject(Store); - students$ = this.store.select(StudentSelectors.selectStudents); -} diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.actions.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.actions.ts deleted file mode 100644 index ff41af34e..000000000 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.actions.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Teacher } from '@angular-challenges/ngrx-notification/model'; -import { createActionGroup, props } from '@ngrx/store'; - -export const teacherActions = createActionGroup({ - source: 'Teacher API', - events: { - 'Add One Teacher': props<{ teacher: Teacher }>(), - 'Add All Teachers': props<{ teachers: Teacher[] }>(), - }, -}); diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts deleted file mode 100644 index 43c3fab0b..000000000 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { inject, Injectable } from '@angular/core'; -import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { map, switchMap } from 'rxjs'; -import { appActions } from '../../app.actions'; -import { HttpService } from '../../data-access/http.service'; -import { teacherActions } from './teacher.actions'; - -@Injectable() -export class TeacherEffects { - private actions$ = inject(Actions); - private httpService = inject(HttpService); - - loadTeachers$ = createEffect(() => - this.actions$.pipe( - ofType(appActions.initApp), - switchMap(() => - this.httpService - .getAllTeachers() - .pipe(map((teachers) => teacherActions.addAllTeachers({ teachers }))), - ), - ), - ); -} diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts deleted file mode 100644 index d793b9646..000000000 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Teacher } from '@angular-challenges/ngrx-notification/model'; -import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity'; -import { createReducer, on } from '@ngrx/store'; -import { teacherActions } from './teacher.actions'; - -export const teachersFeatureKey = 'teachers'; - -export type TeacherState = EntityState; - -export const teacherAdapter: EntityAdapter = - createEntityAdapter(); - -export const teacherReducer = createReducer( - teacherAdapter.getInitialState(), - on(teacherActions.addOneTeacher, (state, { teacher }) => - teacherAdapter.upsertOne(teacher, state), - ), - on(teacherActions.addAllTeachers, (state, { teachers }) => - teacherAdapter.setAll(teachers, state), - ), -); - -export const { selectIds, selectEntities, selectAll, selectTotal } = - teacherAdapter.getSelectors(); diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts deleted file mode 100644 index a32e82c2b..000000000 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { - TeacherState, - teacherAdapter, - teachersFeatureKey, -} from './teacher.reducer'; - -const selectTeacherState = - createFeatureSelector(teachersFeatureKey); - -export const { selectAll } = teacherAdapter.getSelectors(); - -const selectTeachers = createSelector(selectTeacherState, selectAll); - -export const TeacherSelectors = { - selectTeachers, -}; diff --git a/apps/ngrx/notification/src/app/teacher/teacher.component.ts b/apps/ngrx/notification/src/app/teacher/teacher.component.ts deleted file mode 100644 index 63e812200..000000000 --- a/apps/ngrx/notification/src/app/teacher/teacher.component.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { AsyncPipe, NgFor } from '@angular/common'; -import { Component } from '@angular/core'; -import { Store } from '@ngrx/store'; -import { TeacherSelectors } from './store/teacher.selectors'; - -@Component({ - standalone: true, - imports: [NgFor, AsyncPipe], - selector: 'teacher', - template: ` -

TEACHERS

-
- {{ teacher.firstname }} {{ teacher.lastname }} - {{ teacher.version }} -
- `, - styles: [ - ` - :host { - display: block; - width: fit-content; - height: fit-content; - border: 1px solid red; - padding: 4px; - } - `, - ], -}) -export class TeacherComponent { - teacher$ = this.store.select(TeacherSelectors.selectTeachers); - - constructor(private store: Store) {} -} diff --git a/apps/ngrx/notification/src/index.html b/apps/ngrx/notification/src/index.html deleted file mode 100644 index cc46b13b2..000000000 --- a/apps/ngrx/notification/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - NgrxNotification - - - - - - - - diff --git a/apps/ngrx/notification/src/main.ts b/apps/ngrx/notification/src/main.ts deleted file mode 100644 index 6f91f21a3..000000000 --- a/apps/ngrx/notification/src/main.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { appConfig } from './app/app.config'; - -import { bootstrapApplication } from '@angular/platform-browser'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/ngrx/notification/src/polyfills.ts b/apps/ngrx/notification/src/polyfills.ts deleted file mode 100644 index e4555ed11..000000000 --- a/apps/ngrx/notification/src/polyfills.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes recent versions of Safari, Chrome (including - * Opera), Edge on the desktop, and iOS and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/*************************************************************************************************** - * BROWSER POLYFILLS - */ - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/apps/ngrx/notification/tsconfig.app.json b/apps/ngrx/notification/tsconfig.app.json deleted file mode 100644 index 7a4dbc47e..000000000 --- a/apps/ngrx/notification/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false - }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/ngrx/notification/tsconfig.editor.json b/apps/ngrx/notification/tsconfig.editor.json deleted file mode 100644 index 3d4f1db8b..000000000 --- a/apps/ngrx/notification/tsconfig.editor.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": [ - "**/*.ts", - "../../../libs/ngrx-notification/backend/src/lib/fake-backend.service.ts" - ], - "compilerOptions": { - "types": [] - } -} diff --git a/apps/ngrx/notification/tsconfig.json b/apps/ngrx/notification/tsconfig.json deleted file mode 100644 index b2dbbf22e..000000000 --- a/apps/ngrx/notification/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2020", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/nx/42-static-vs-dynamic-import/.eslintrc.json b/apps/nx/42-static-vs-dynamic-import/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/nx/42-static-vs-dynamic-import/README.md b/apps/nx/42-static-vs-dynamic-import/README.md new file mode 100644 index 000000000..a08abaa82 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/README.md @@ -0,0 +1,13 @@ +# Static vs Dynamic Import + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve nx-static-vs-dynamic-import +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/nx/42-static-dynamic-import/). diff --git a/apps/nx/42-static-vs-dynamic-import/project.json b/apps/nx/42-static-vs-dynamic-import/project.json new file mode 100644 index 000000000..68332bbc6 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/project.json @@ -0,0 +1,74 @@ +{ + "name": "nx-static-vs-dynamic-import", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/nx/42-static-vs-dynamic-import/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/nx/42-static-vs-dynamic-import", + "index": "apps/nx/42-static-vs-dynamic-import/src/index.html", + "browser": "apps/nx/42-static-vs-dynamic-import/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/nx/42-static-vs-dynamic-import/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/nx/42-static-vs-dynamic-import/src/favicon.ico", + "apps/nx/42-static-vs-dynamic-import/src/assets" + ], + "styles": [ + "apps/nx/42-static-vs-dynamic-import/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all", + "sourceMap": true + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "nx-static-vs-dynamic-import:build:production" + }, + "development": { + "buildTarget": "nx-static-vs-dynamic-import:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "nx-static-vs-dynamic-import:build" + } + } + } +} diff --git a/apps/nx/42-static-vs-dynamic-import/src/app/app.component.ts b/apps/nx/42-static-vs-dynamic-import/src/app/app.component.ts new file mode 100644 index 000000000..59be617e8 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/src/app/app.component.ts @@ -0,0 +1,26 @@ +import { + UserComponent, + type User, +} from '@angular-challenges/static-dynamic-import/users'; +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [UserComponent, RouterOutlet], + selector: 'app-root', + template: ` + Author: + + + `, + host: { + class: 'flex flex-col', + }, +}) +export class AppComponent { + author: User = { + name: 'Thomas', + lastName: 'Laforge', + country: 'France', + }; +} diff --git a/apps/nx/static-dynamic-import/src/app/app.config.ts b/apps/nx/42-static-vs-dynamic-import/src/app/app.config.ts similarity index 100% rename from apps/nx/static-dynamic-import/src/app/app.config.ts rename to apps/nx/42-static-vs-dynamic-import/src/app/app.config.ts diff --git a/apps/forms/control-value-accessor/src/assets/.gitkeep b/apps/nx/42-static-vs-dynamic-import/src/assets/.gitkeep similarity index 100% rename from apps/forms/control-value-accessor/src/assets/.gitkeep rename to apps/nx/42-static-vs-dynamic-import/src/assets/.gitkeep diff --git a/apps/performance/default-onpush/src/favicon.ico b/apps/nx/42-static-vs-dynamic-import/src/favicon.ico similarity index 100% rename from apps/performance/default-onpush/src/favicon.ico rename to apps/nx/42-static-vs-dynamic-import/src/favicon.ico diff --git a/apps/nx/42-static-vs-dynamic-import/src/index.html b/apps/nx/42-static-vs-dynamic-import/src/index.html new file mode 100644 index 000000000..1b4f2a84b --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/src/index.html @@ -0,0 +1,16 @@ + + + + + nx-static-vs-dynamic-import + + + + + + + + + diff --git a/apps/nx/42-static-vs-dynamic-import/src/main.ts b/apps/nx/42-static-vs-dynamic-import/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/performance/ngfor-optimize/src/styles.scss b/apps/nx/42-static-vs-dynamic-import/src/styles.scss similarity index 100% rename from apps/performance/ngfor-optimize/src/styles.scss rename to apps/nx/42-static-vs-dynamic-import/src/styles.scss diff --git a/apps/performance/ngfor-optimize/tailwind.config.js b/apps/nx/42-static-vs-dynamic-import/tailwind.config.js similarity index 100% rename from apps/performance/ngfor-optimize/tailwind.config.js rename to apps/nx/42-static-vs-dynamic-import/tailwind.config.js diff --git a/apps/nx/42-static-vs-dynamic-import/tsconfig.app.json b/apps/nx/42-static-vs-dynamic-import/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/view-transition/tsconfig.editor.json b/apps/nx/42-static-vs-dynamic-import/tsconfig.editor.json similarity index 100% rename from apps/angular/view-transition/tsconfig.editor.json rename to apps/nx/42-static-vs-dynamic-import/tsconfig.editor.json diff --git a/apps/nx/42-static-vs-dynamic-import/tsconfig.json b/apps/nx/42-static-vs-dynamic-import/tsconfig.json new file mode 100644 index 000000000..7cfcc3b0b --- /dev/null +++ b/apps/nx/42-static-vs-dynamic-import/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/nx/static-dynamic-import/README.md b/apps/nx/static-dynamic-import/README.md deleted file mode 100644 index 54691c75b..000000000 --- a/apps/nx/static-dynamic-import/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Static vs Dynamic Import - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve nx-static-dynamic-import -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/nx/42-static-dynamic-import/). diff --git a/apps/nx/static-dynamic-import/project.json b/apps/nx/static-dynamic-import/project.json deleted file mode 100644 index c0208b075..000000000 --- a/apps/nx/static-dynamic-import/project.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "nx-static-dynamic-import", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/nx/static-dynamic-import/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/nx/static-dynamic-import", - "index": "apps/nx/static-dynamic-import/src/index.html", - "browser": "apps/nx/static-dynamic-import/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/nx/static-dynamic-import/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/nx/static-dynamic-import/src/favicon.ico", - "apps/nx/static-dynamic-import/src/assets" - ], - "styles": [ - "apps/nx/static-dynamic-import/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all", - "sourceMap": true - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "nx-static-dynamic-import:build:production" - }, - "development": { - "buildTarget": "nx-static-dynamic-import:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "nx-static-dynamic-import:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - } - } -} diff --git a/apps/nx/static-dynamic-import/src/app/app.component.ts b/apps/nx/static-dynamic-import/src/app/app.component.ts deleted file mode 100644 index 9c5bd67d4..000000000 --- a/apps/nx/static-dynamic-import/src/app/app.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - UserComponent, - type User, -} from '@angular-challenges/static-dynamic-import/users'; -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [UserComponent, RouterOutlet], - selector: 'app-root', - template: ` - Author: - - - `, - host: { - class: 'flex flex-col', - }, -}) -export class AppComponent { - author: User = { - name: 'Thomas', - lastName: 'Laforge', - country: 'France', - }; -} diff --git a/apps/nx/static-dynamic-import/src/index.html b/apps/nx/static-dynamic-import/src/index.html deleted file mode 100644 index 77adec4af..000000000 --- a/apps/nx/static-dynamic-import/src/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - nx-static-dynamic-import - - - - - - - - - diff --git a/apps/nx/static-dynamic-import/src/main.ts b/apps/nx/static-dynamic-import/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/nx/static-dynamic-import/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/nx/static-dynamic-import/tsconfig.app.json b/apps/nx/static-dynamic-import/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/nx/static-dynamic-import/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/nx/static-dynamic-import/tsconfig.json b/apps/nx/static-dynamic-import/tsconfig.json deleted file mode 100644 index b94f8837d..000000000 --- a/apps/nx/static-dynamic-import/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/angular/styling/.eslintrc.json b/apps/performance/12-optimize-change-detection/.eslintrc.json similarity index 100% rename from apps/angular/styling/.eslintrc.json rename to apps/performance/12-optimize-change-detection/.eslintrc.json diff --git a/apps/performance/12-optimize-change-detection/README.md b/apps/performance/12-optimize-change-detection/README.md new file mode 100644 index 000000000..52fe319d7 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/README.md @@ -0,0 +1,13 @@ +# Optimize Change Detection + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve performance-optimize-change-detection +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/12-performance-optimize-change-detection/). diff --git a/apps/performance/12-optimize-change-detection/jest.config.ts b/apps/performance/12-optimize-change-detection/jest.config.ts new file mode 100644 index 000000000..c56a308c8 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/jest.config.ts @@ -0,0 +1,24 @@ +/* eslint-disable */ +module.exports = { + displayName: 'performance-optimize-change-detection', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: {}, + coverageDirectory: + '../../../coverage/apps/performance/12-optimize-change-detection', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/performance/12-optimize-change-detection/project.json b/apps/performance/12-optimize-change-detection/project.json new file mode 100644 index 000000000..88812e3cd --- /dev/null +++ b/apps/performance/12-optimize-change-detection/project.json @@ -0,0 +1,86 @@ +{ + "name": "performance-optimize-change-detection", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/performance/12-optimize-change-detection/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/12-optimize-change-detection", + "index": "apps/performance/12-optimize-change-detection/src/index.html", + "main": "apps/performance/12-optimize-change-detection/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/12-optimize-change-detection/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/performance/12-optimize-change-detection/src/favicon.ico", + "apps/performance/12-optimize-change-detection/src/assets" + ], + "styles": [ + "apps/performance/12-optimize-change-detection/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-optimize-change-detection:build:production" + }, + "development": { + "buildTarget": "performance-optimize-change-detection:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "performance-optimize-change-detection:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/performance/12-optimize-change-detection/src/app/app.component.ts b/apps/performance/12-optimize-change-detection/src/app/app.component.ts new file mode 100644 index 000000000..b6e8a7c0a --- /dev/null +++ b/apps/performance/12-optimize-change-detection/src/app/app.component.ts @@ -0,0 +1,50 @@ +import { Component, HostListener, signal } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` +
Top
+
Middle
+
Bottom
+ @if (displayButton()) { + + } + `, + styles: [ + ` + :host { + height: 1500px; + display: flex; + flex-direction: column; + justify-content: space-between; + + button { + position: fixed; + bottom: 1rem; + left: 1rem; + z-index: 1; + padding: 1rem; + } + } + `, + ], +}) +export class AppComponent { + title = 'scroll-cd'; + + public displayButton = signal(false); + + @HostListener('window:scroll', ['$event']) + onScroll() { + const pos = window.scrollY; + this.displayButton.set(pos > 50); + } + + goToTop() { + window.scroll({ + top: 0, + left: 0, + behavior: 'smooth', + }); + } +} diff --git a/apps/ngrx/effect-selector/src/assets/.gitkeep b/apps/performance/12-optimize-change-detection/src/assets/.gitkeep similarity index 100% rename from apps/ngrx/effect-selector/src/assets/.gitkeep rename to apps/performance/12-optimize-change-detection/src/assets/.gitkeep diff --git a/apps/performance/memoized/src/favicon.ico b/apps/performance/12-optimize-change-detection/src/favicon.ico similarity index 100% rename from apps/performance/memoized/src/favicon.ico rename to apps/performance/12-optimize-change-detection/src/favicon.ico diff --git a/apps/performance/12-optimize-change-detection/src/index.html b/apps/performance/12-optimize-change-detection/src/index.html new file mode 100644 index 000000000..c1cb61764 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-optimize-change-detection + + + + + + + + diff --git a/apps/performance/12-optimize-change-detection/src/main.ts b/apps/performance/12-optimize-change-detection/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/performance/12-optimize-change-detection/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/angular/styling/src/styles.scss b/apps/performance/12-optimize-change-detection/src/styles.scss similarity index 100% rename from apps/angular/styling/src/styles.scss rename to apps/performance/12-optimize-change-detection/src/styles.scss diff --git a/apps/performance/12-optimize-change-detection/src/test-setup.ts b/apps/performance/12-optimize-change-detection/src/test-setup.ts new file mode 100644 index 000000000..58c511e08 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/src/test-setup.ts @@ -0,0 +1,3 @@ +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/performance/12-optimize-change-detection/tsconfig.app.json b/apps/performance/12-optimize-change-detection/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/forms/control-value-accessor/tsconfig.editor.json b/apps/performance/12-optimize-change-detection/tsconfig.editor.json similarity index 100% rename from apps/forms/control-value-accessor/tsconfig.editor.json rename to apps/performance/12-optimize-change-detection/tsconfig.editor.json diff --git a/apps/performance/12-optimize-change-detection/tsconfig.json b/apps/performance/12-optimize-change-detection/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/performance/12-optimize-change-detection/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/12-optimize-change-detection/tsconfig.spec.json b/apps/performance/12-optimize-change-detection/tsconfig.spec.json new file mode 100644 index 000000000..032d49d7a --- /dev/null +++ b/apps/performance/12-optimize-change-detection/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/performance/default-onpush/.eslintrc.json b/apps/performance/34-default-vs-onpush/.eslintrc.json similarity index 100% rename from apps/performance/default-onpush/.eslintrc.json rename to apps/performance/34-default-vs-onpush/.eslintrc.json diff --git a/apps/performance/34-default-vs-onpush/README.md b/apps/performance/34-default-vs-onpush/README.md new file mode 100644 index 000000000..ab82704b5 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/README.md @@ -0,0 +1,13 @@ +# Default vs OnPush + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve performance-default-vs-onpush +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/34-default-onpush/). diff --git a/apps/performance/34-default-vs-onpush/project.json b/apps/performance/34-default-vs-onpush/project.json new file mode 100644 index 000000000..d772d9d2e --- /dev/null +++ b/apps/performance/34-default-vs-onpush/project.json @@ -0,0 +1,76 @@ +{ + "name": "performance-default-vs-onpush", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/34-default-vs-onpush/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/34-default-vs-onpush", + "index": "apps/performance/34-default-vs-onpush/src/index.html", + "main": "apps/performance/34-default-vs-onpush/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/34-default-vs-onpush/tsconfig.app.json", + "assets": [ + "apps/performance/34-default-vs-onpush/src/favicon.ico", + "apps/performance/34-default-vs-onpush/src/assets" + ], + "styles": [ + "apps/performance/34-default-vs-onpush/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-default-vs-onpush:build:production" + }, + "development": { + "buildTarget": "performance-default-vs-onpush:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "performance-default-vs-onpush:build" + } + } + } +} diff --git a/apps/performance/34-default-vs-onpush/src/app/app.component.ts b/apps/performance/34-default-vs-onpush/src/app/app.component.ts new file mode 100644 index 000000000..88b0a6571 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/app/app.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { randFirstName } from '@ngneat/falso'; +import { PersonListComponent } from './person-list.component'; +import { RandomComponent } from './random.component'; + +@Component({ + imports: [PersonListComponent, RandomComponent], + selector: 'app-root', + template: ` + + +
+ + +
+ `, +}) +export class AppComponent { + girlList = randFirstName({ gender: 'female', length: 10 }); + boyList = randFirstName({ gender: 'male', length: 10 }); +} diff --git a/apps/performance/default-onpush/src/app/app.config.ts b/apps/performance/34-default-vs-onpush/src/app/app.config.ts similarity index 100% rename from apps/performance/default-onpush/src/app/app.config.ts rename to apps/performance/34-default-vs-onpush/src/app/app.config.ts diff --git a/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts b/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts new file mode 100644 index 000000000..e34a39e87 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts @@ -0,0 +1,70 @@ +import { Component, input } from '@angular/core'; + +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { TitleCasePipe } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatListModule } from '@angular/material/list'; + +@Component({ + selector: 'app-person-list', + imports: [ + FormsModule, + MatListModule, + MatFormFieldModule, + MatInputModule, + MatChipsModule, + CDFlashingDirective, + TitleCasePipe, + ], + template: ` +

+ {{ title() | titlecase }} +

+ + + + + + + @if (names()?.length === 0) { +
Empty list
+ } + @for (name of names(); track name) { + +
+

+ {{ name }} +

+
+
+ } + @if (names()?.length !== 0) { + + } +
+ `, + host: { + class: 'w-full flex flex-col items-center', + }, +}) +export class PersonListComponent { + names = input([]); + title = input(''); + + label = ''; + + handleKey(event: KeyboardEvent) { + if (event.key === 'Enter') { + this.names()?.unshift(this.label); + this.label = ''; + } + } +} diff --git a/apps/performance/default-onpush/src/app/random.component.ts b/apps/performance/34-default-vs-onpush/src/app/random.component.ts similarity index 93% rename from apps/performance/default-onpush/src/app/random.component.ts rename to apps/performance/34-default-vs-onpush/src/app/random.component.ts index d46cdd053..71479e28d 100644 --- a/apps/performance/default-onpush/src/app/random.component.ts +++ b/apps/performance/34-default-vs-onpush/src/app/random.component.ts @@ -3,7 +3,6 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-random', - standalone: true, template: `
I do nothing but I'm here
`, diff --git a/apps/ngrx/notification/src/assets/.gitkeep b/apps/performance/34-default-vs-onpush/src/assets/.gitkeep similarity index 100% rename from apps/ngrx/notification/src/assets/.gitkeep rename to apps/performance/34-default-vs-onpush/src/assets/.gitkeep diff --git a/apps/performance/ngfor-biglist/src/favicon.ico b/apps/performance/34-default-vs-onpush/src/favicon.ico similarity index 100% rename from apps/performance/ngfor-biglist/src/favicon.ico rename to apps/performance/34-default-vs-onpush/src/favicon.ico diff --git a/apps/performance/34-default-vs-onpush/src/index.html b/apps/performance/34-default-vs-onpush/src/index.html new file mode 100644 index 000000000..251489ea3 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-default-vs-onpush + + + + + + + + diff --git a/apps/performance/34-default-vs-onpush/src/main.ts b/apps/performance/34-default-vs-onpush/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/rxjs/catch-error/src/styles.scss b/apps/performance/34-default-vs-onpush/src/styles.scss similarity index 100% rename from apps/rxjs/catch-error/src/styles.scss rename to apps/performance/34-default-vs-onpush/src/styles.scss diff --git a/apps/rxjs/catch-error/tailwind.config.js b/apps/performance/34-default-vs-onpush/tailwind.config.js similarity index 100% rename from apps/rxjs/catch-error/tailwind.config.js rename to apps/performance/34-default-vs-onpush/tailwind.config.js diff --git a/apps/performance/34-default-vs-onpush/tsconfig.app.json b/apps/performance/34-default-vs-onpush/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/performance/default-onpush/tsconfig.editor.json b/apps/performance/34-default-vs-onpush/tsconfig.editor.json similarity index 100% rename from apps/performance/default-onpush/tsconfig.editor.json rename to apps/performance/34-default-vs-onpush/tsconfig.editor.json diff --git a/apps/performance/34-default-vs-onpush/tsconfig.json b/apps/performance/34-default-vs-onpush/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/memoized/.eslintrc.json b/apps/performance/35-memoization/.eslintrc.json similarity index 100% rename from apps/performance/memoized/.eslintrc.json rename to apps/performance/35-memoization/.eslintrc.json diff --git a/apps/performance/35-memoization/README.md b/apps/performance/35-memoization/README.md new file mode 100644 index 000000000..a06a0e91d --- /dev/null +++ b/apps/performance/35-memoization/README.md @@ -0,0 +1,13 @@ +# Memoization + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve performance-memoization +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/35-memoize/). diff --git a/apps/performance/35-memoization/project.json b/apps/performance/35-memoization/project.json new file mode 100644 index 000000000..03f97cb21 --- /dev/null +++ b/apps/performance/35-memoization/project.json @@ -0,0 +1,76 @@ +{ + "name": "performance-memoization", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/35-memoization/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/35-memoization", + "index": "apps/performance/35-memoization/src/index.html", + "main": "apps/performance/35-memoization/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/35-memoization/tsconfig.app.json", + "assets": [ + "apps/performance/35-memoization/src/favicon.ico", + "apps/performance/35-memoization/src/assets" + ], + "styles": [ + "apps/performance/35-memoization/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-memoization:build:production" + }, + "development": { + "buildTarget": "performance-memoization:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "performance-memoization:build" + } + } + } +} diff --git a/apps/performance/35-memoization/src/app/app.component.ts b/apps/performance/35-memoization/src/app/app.component.ts new file mode 100644 index 000000000..44e55db4f --- /dev/null +++ b/apps/performance/35-memoization/src/app/app.component.ts @@ -0,0 +1,24 @@ +import { Component } from '@angular/core'; +import { generateList } from './generateList'; +import { PersonListComponent } from './person-list.component'; + +@Component({ + imports: [PersonListComponent], + selector: 'app-root', + template: ` +

Performance is key!!

+ + + @if (loadList) { + + } + `, +}) +export class AppComponent { + persons = generateList(); + loadList = false; +} diff --git a/apps/performance/memoized/src/app/app.config.ts b/apps/performance/35-memoization/src/app/app.config.ts similarity index 100% rename from apps/performance/memoized/src/app/app.config.ts rename to apps/performance/35-memoization/src/app/app.config.ts diff --git a/apps/performance/memoized/src/app/generateList.ts b/apps/performance/35-memoization/src/app/generateList.ts similarity index 100% rename from apps/performance/memoized/src/app/generateList.ts rename to apps/performance/35-memoization/src/app/generateList.ts diff --git a/apps/performance/35-memoization/src/app/person-list.component.ts b/apps/performance/35-memoization/src/app/person-list.component.ts new file mode 100644 index 000000000..a97ec64c9 --- /dev/null +++ b/apps/performance/35-memoization/src/app/person-list.component.ts @@ -0,0 +1,65 @@ +import { Component, input } from '@angular/core'; + +import { TitleCasePipe } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatListModule } from '@angular/material/list'; +import { Person } from './person.model'; + +const fibonacci = (num: number): number => { + if (num === 1 || num === 2) { + return 1; + } + return fibonacci(num - 1) + fibonacci(num - 2); +}; + +@Component({ + selector: 'app-person-list', + imports: [ + FormsModule, + MatListModule, + MatFormFieldModule, + MatInputModule, + MatChipsModule, + TitleCasePipe, + ], + template: ` +

+ {{ title() | titlecase }} +

+ + + + + + + @for (person of persons(); track person.name) { + +
+

{{ person.name }}

+ {{ calculate(person.fib) }} +
+
+ } +
+ `, + host: { + class: 'w-full flex flex-col items-center', + }, +}) +export class PersonListComponent { + persons = input(); + title = input(''); + + label = ''; + + calculate(num: number) { + return fibonacci(num); + } +} diff --git a/apps/performance/memoized/src/app/person.model.ts b/apps/performance/35-memoization/src/app/person.model.ts similarity index 100% rename from apps/performance/memoized/src/app/person.model.ts rename to apps/performance/35-memoization/src/app/person.model.ts diff --git a/apps/nx/static-dynamic-import/src/assets/.gitkeep b/apps/performance/35-memoization/src/assets/.gitkeep similarity index 100% rename from apps/nx/static-dynamic-import/src/assets/.gitkeep rename to apps/performance/35-memoization/src/assets/.gitkeep diff --git a/apps/performance/ngfor-optimize/src/favicon.ico b/apps/performance/35-memoization/src/favicon.ico similarity index 100% rename from apps/performance/ngfor-optimize/src/favicon.ico rename to apps/performance/35-memoization/src/favicon.ico diff --git a/apps/performance/35-memoization/src/index.html b/apps/performance/35-memoization/src/index.html new file mode 100644 index 000000000..39ddb9045 --- /dev/null +++ b/apps/performance/35-memoization/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-memoization + + + + + + + + diff --git a/apps/performance/35-memoization/src/main.ts b/apps/performance/35-memoization/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/performance/35-memoization/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/checkbox/src/styles.scss b/apps/performance/35-memoization/src/styles.scss similarity index 100% rename from apps/testing/checkbox/src/styles.scss rename to apps/performance/35-memoization/src/styles.scss diff --git a/apps/testing/checkbox/tailwind.config.js b/apps/performance/35-memoization/tailwind.config.js similarity index 100% rename from apps/testing/checkbox/tailwind.config.js rename to apps/performance/35-memoization/tailwind.config.js diff --git a/apps/performance/35-memoization/tsconfig.app.json b/apps/performance/35-memoization/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/35-memoization/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/nx/static-dynamic-import/tsconfig.editor.json b/apps/performance/35-memoization/tsconfig.editor.json similarity index 100% rename from apps/nx/static-dynamic-import/tsconfig.editor.json rename to apps/performance/35-memoization/tsconfig.editor.json diff --git a/apps/performance/35-memoization/tsconfig.json b/apps/performance/35-memoization/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/performance/35-memoization/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/ngfor-biglist/.eslintrc.json b/apps/performance/36-ngfor-optimization/.eslintrc.json similarity index 100% rename from apps/performance/ngfor-biglist/.eslintrc.json rename to apps/performance/36-ngfor-optimization/.eslintrc.json diff --git a/apps/performance/36-ngfor-optimization/README.md b/apps/performance/36-ngfor-optimization/README.md new file mode 100644 index 000000000..2ee0bb20e --- /dev/null +++ b/apps/performance/36-ngfor-optimization/README.md @@ -0,0 +1,13 @@ +# NgFor Optimization + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve performance-ngfor-optimization +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/36-ngfor-optimize/). diff --git a/apps/performance/36-ngfor-optimization/jest.config.ts b/apps/performance/36-ngfor-optimization/jest.config.ts new file mode 100644 index 000000000..bc40be0df --- /dev/null +++ b/apps/performance/36-ngfor-optimization/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'performance-ngfor-optimization', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/performance/36-ngfor-optimization', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/performance/36-ngfor-optimization/project.json b/apps/performance/36-ngfor-optimization/project.json new file mode 100644 index 000000000..8a27c862e --- /dev/null +++ b/apps/performance/36-ngfor-optimization/project.json @@ -0,0 +1,87 @@ +{ + "name": "performance-ngfor-optimization", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/36-ngfor-optimization/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/36-ngfor-optimization", + "index": "apps/performance/36-ngfor-optimization/src/index.html", + "main": "apps/performance/36-ngfor-optimization/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/36-ngfor-optimization/tsconfig.app.json", + "assets": [ + "apps/performance/36-ngfor-optimization/src/favicon.ico", + "apps/performance/36-ngfor-optimization/src/assets" + ], + "styles": [ + "apps/performance/36-ngfor-optimization/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-ngfor-optimization:build:production" + }, + "development": { + "buildTarget": "performance-ngfor-optimization:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "performance-ngfor-optimization:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/performance/36-ngfor-optimization/src/app/app.component.ts b/apps/performance/36-ngfor-optimization/src/app/app.component.ts new file mode 100644 index 000000000..f1aa9f133 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/src/app/app.component.ts @@ -0,0 +1,57 @@ +import { Component, OnInit, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { PersonService } from './list.service'; +import { PersonListComponent } from './person-list.component'; + +@Component({ + imports: [ + PersonListComponent, + FormsModule, + MatFormFieldModule, + MatInputModule, + ], + providers: [PersonService], + selector: 'app-root', + template: ` +

+ List of Persons +

+ + + + + + + `, + host: { + class: 'flex items-center flex-col gap-5', + }, +}) +export class AppComponent implements OnInit { + readonly personService = inject(PersonService); + readonly persons = this.personService.persons; + + label = ''; + + ngOnInit(): void { + this.personService.loadPersons(); + } + + handleKey(event: any) { + if (event.keyCode === 13) { + this.personService.addPerson(this.label); + this.label = ''; + } + } +} diff --git a/apps/performance/ngfor-biglist/src/app/app.config.ts b/apps/performance/36-ngfor-optimization/src/app/app.config.ts similarity index 100% rename from apps/performance/ngfor-biglist/src/app/app.config.ts rename to apps/performance/36-ngfor-optimization/src/app/app.config.ts diff --git a/apps/performance/ngfor-optimize/src/app/generateList.ts b/apps/performance/36-ngfor-optimization/src/app/generateList.ts similarity index 100% rename from apps/performance/ngfor-optimize/src/app/generateList.ts rename to apps/performance/36-ngfor-optimization/src/app/generateList.ts diff --git a/apps/performance/ngfor-biglist/src/app/list.service.ts b/apps/performance/36-ngfor-optimization/src/app/list.service.ts similarity index 100% rename from apps/performance/ngfor-biglist/src/app/list.service.ts rename to apps/performance/36-ngfor-optimization/src/app/list.service.ts diff --git a/apps/performance/36-ngfor-optimization/src/app/person-list.component.ts b/apps/performance/36-ngfor-optimization/src/app/person-list.component.ts new file mode 100644 index 000000000..c98aaa4ee --- /dev/null +++ b/apps/performance/36-ngfor-optimization/src/app/person-list.component.ts @@ -0,0 +1,33 @@ +import { Component, input, output } from '@angular/core'; +import { Person } from './person.model'; + +@Component({ + selector: 'app-person-list', + template: ` + @for (person of persons(); track person.email) { +
+

{{ person.name }}

+
+ + +
+
+ } + `, + host: { + class: 'w-full flex flex-col', + }, +}) +export class PersonListComponent { + persons = input(); + delete = output(); + update = output(); +} diff --git a/apps/performance/ngfor-biglist/src/app/person.model.ts b/apps/performance/36-ngfor-optimization/src/app/person.model.ts similarity index 100% rename from apps/performance/ngfor-biglist/src/app/person.model.ts rename to apps/performance/36-ngfor-optimization/src/app/person.model.ts diff --git a/apps/performance/christmas-web-worker/src/assets/.gitkeep b/apps/performance/36-ngfor-optimization/src/assets/.gitkeep similarity index 100% rename from apps/performance/christmas-web-worker/src/assets/.gitkeep rename to apps/performance/36-ngfor-optimization/src/assets/.gitkeep diff --git a/apps/performance/scroll-cd/src/favicon.ico b/apps/performance/36-ngfor-optimization/src/favicon.ico similarity index 100% rename from apps/performance/scroll-cd/src/favicon.ico rename to apps/performance/36-ngfor-optimization/src/favicon.ico diff --git a/apps/performance/36-ngfor-optimization/src/index.html b/apps/performance/36-ngfor-optimization/src/index.html new file mode 100644 index 000000000..07ec600a8 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-ngfor-optimization + + + + + + + + diff --git a/apps/performance/36-ngfor-optimization/src/main.ts b/apps/performance/36-ngfor-optimization/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/modal/src/styles.scss b/apps/performance/36-ngfor-optimization/src/styles.scss similarity index 100% rename from apps/testing/modal/src/styles.scss rename to apps/performance/36-ngfor-optimization/src/styles.scss diff --git a/apps/performance/36-ngfor-optimization/src/test-setup.ts b/apps/performance/36-ngfor-optimization/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/create-harness/tailwind.config.js b/apps/performance/36-ngfor-optimization/tailwind.config.js similarity index 100% rename from apps/testing/create-harness/tailwind.config.js rename to apps/performance/36-ngfor-optimization/tailwind.config.js diff --git a/apps/performance/36-ngfor-optimization/tsconfig.app.json b/apps/performance/36-ngfor-optimization/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/performance/ngfor-optimize/tsconfig.editor.json b/apps/performance/36-ngfor-optimization/tsconfig.editor.json similarity index 100% rename from apps/performance/ngfor-optimize/tsconfig.editor.json rename to apps/performance/36-ngfor-optimization/tsconfig.editor.json diff --git a/apps/performance/36-ngfor-optimization/tsconfig.json b/apps/performance/36-ngfor-optimization/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/36-ngfor-optimization/tsconfig.spec.json b/apps/performance/36-ngfor-optimization/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/performance/36-ngfor-optimization/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/performance/ngfor-optimize/.eslintrc.json b/apps/performance/37-optimize-big-list/.eslintrc.json similarity index 100% rename from apps/performance/ngfor-optimize/.eslintrc.json rename to apps/performance/37-optimize-big-list/.eslintrc.json diff --git a/apps/performance/37-optimize-big-list/README.md b/apps/performance/37-optimize-big-list/README.md new file mode 100644 index 000000000..1d8e134c2 --- /dev/null +++ b/apps/performance/37-optimize-big-list/README.md @@ -0,0 +1,13 @@ +# NgFor optimize big list + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve performance-optimize-big-list +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/37-ngfor-biglist/). diff --git a/apps/performance/37-optimize-big-list/project.json b/apps/performance/37-optimize-big-list/project.json new file mode 100644 index 000000000..3ecb24d36 --- /dev/null +++ b/apps/performance/37-optimize-big-list/project.json @@ -0,0 +1,76 @@ +{ + "name": "performance-optimize-big-list", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/37-optimize-big-list/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/37-optimize-big-list", + "index": "apps/performance/37-optimize-big-list/src/index.html", + "main": "apps/performance/37-optimize-big-list/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/37-optimize-big-list/tsconfig.app.json", + "assets": [ + "apps/performance/37-optimize-big-list/src/favicon.ico", + "apps/performance/37-optimize-big-list/src/assets" + ], + "styles": [ + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "apps/performance/37-optimize-big-list/src/styles.scss" + ], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-optimize-big-list:build:production" + }, + "development": { + "buildTarget": "performance-optimize-big-list:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "performance-optimize-big-list:build" + } + } + } +} diff --git a/apps/performance/37-optimize-big-list/src/app/app.component.ts b/apps/performance/37-optimize-big-list/src/app/app.component.ts new file mode 100644 index 000000000..a5f121b22 --- /dev/null +++ b/apps/performance/37-optimize-big-list/src/app/app.component.ts @@ -0,0 +1,38 @@ +import { Component, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { generateList } from './generateList'; +import { PersonService } from './list.service'; +import { PersonListComponent } from './person-list.component'; + +@Component({ + imports: [ + PersonListComponent, + FormsModule, + MatFormFieldModule, + MatInputModule, + ], + providers: [PersonService], + selector: 'app-root', + template: ` + + + @if (loadList()) { + + } + `, + host: { + class: 'flex items-center flex-col gap-5', + }, +}) +export class AppComponent { + readonly persons = signal(generateList()); + readonly loadList = signal(false); + + label = ''; +} diff --git a/apps/performance/ngfor-optimize/src/app/app.config.ts b/apps/performance/37-optimize-big-list/src/app/app.config.ts similarity index 100% rename from apps/performance/ngfor-optimize/src/app/app.config.ts rename to apps/performance/37-optimize-big-list/src/app/app.config.ts diff --git a/apps/performance/ngfor-biglist/src/app/generateList.ts b/apps/performance/37-optimize-big-list/src/app/generateList.ts similarity index 100% rename from apps/performance/ngfor-biglist/src/app/generateList.ts rename to apps/performance/37-optimize-big-list/src/app/generateList.ts diff --git a/apps/performance/ngfor-optimize/src/app/list.service.ts b/apps/performance/37-optimize-big-list/src/app/list.service.ts similarity index 100% rename from apps/performance/ngfor-optimize/src/app/list.service.ts rename to apps/performance/37-optimize-big-list/src/app/list.service.ts diff --git a/apps/performance/37-optimize-big-list/src/app/person-list.component.ts b/apps/performance/37-optimize-big-list/src/app/person-list.component.ts new file mode 100644 index 000000000..049630476 --- /dev/null +++ b/apps/performance/37-optimize-big-list/src/app/person-list.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; +import { Person } from './person.model'; + +@Component({ + selector: 'app-person-list', + template: ` +
+
+ @for (person of persons(); track person.email) { +
+

{{ person.name }}

+

{{ person.email }}

+
+ } +
+
+ `, + host: { + class: 'w-full flex flex-col', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PersonListComponent { + persons = input(); +} diff --git a/apps/performance/ngfor-optimize/src/app/person.model.ts b/apps/performance/37-optimize-big-list/src/app/person.model.ts similarity index 100% rename from apps/performance/ngfor-optimize/src/app/person.model.ts rename to apps/performance/37-optimize-big-list/src/app/person.model.ts diff --git a/apps/performance/default-onpush/src/assets/.gitkeep b/apps/performance/37-optimize-big-list/src/assets/.gitkeep similarity index 100% rename from apps/performance/default-onpush/src/assets/.gitkeep rename to apps/performance/37-optimize-big-list/src/assets/.gitkeep diff --git a/apps/rxjs/catch-error/src/favicon.ico b/apps/performance/37-optimize-big-list/src/favicon.ico similarity index 100% rename from apps/rxjs/catch-error/src/favicon.ico rename to apps/performance/37-optimize-big-list/src/favicon.ico diff --git a/apps/performance/37-optimize-big-list/src/index.html b/apps/performance/37-optimize-big-list/src/index.html new file mode 100644 index 000000000..f93d2d26f --- /dev/null +++ b/apps/performance/37-optimize-big-list/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-optimize-big-list + + + + + + + + diff --git a/apps/performance/37-optimize-big-list/src/main.ts b/apps/performance/37-optimize-big-list/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/performance/37-optimize-big-list/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/typescript/enums-vs-union-types/src/styles.scss b/apps/performance/37-optimize-big-list/src/styles.scss similarity index 100% rename from apps/typescript/enums-vs-union-types/src/styles.scss rename to apps/performance/37-optimize-big-list/src/styles.scss diff --git a/apps/testing/harness/tailwind.config.js b/apps/performance/37-optimize-big-list/tailwind.config.js similarity index 100% rename from apps/testing/harness/tailwind.config.js rename to apps/performance/37-optimize-big-list/tailwind.config.js diff --git a/apps/performance/37-optimize-big-list/tsconfig.app.json b/apps/performance/37-optimize-big-list/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/37-optimize-big-list/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/performance/christmas-web-worker/tsconfig.editor.json b/apps/performance/37-optimize-big-list/tsconfig.editor.json similarity index 100% rename from apps/performance/christmas-web-worker/tsconfig.editor.json rename to apps/performance/37-optimize-big-list/tsconfig.editor.json diff --git a/apps/performance/37-optimize-big-list/tsconfig.json b/apps/performance/37-optimize-big-list/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/performance/37-optimize-big-list/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/christmas-web-worker/.eslintrc.json b/apps/performance/40-web-workers/.eslintrc.json similarity index 100% rename from apps/performance/christmas-web-worker/.eslintrc.json rename to apps/performance/40-web-workers/.eslintrc.json diff --git a/apps/performance/40-web-workers/README.md b/apps/performance/40-web-workers/README.md new file mode 100644 index 000000000..067777a8f --- /dev/null +++ b/apps/performance/40-web-workers/README.md @@ -0,0 +1,13 @@ +# Web workers + +> Author: Thomas Laforge + +### Run Application + +```bash +npx nx serve performance-web-workers +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/40-christmas-web-worker/). diff --git a/apps/performance/40-web-workers/project.json b/apps/performance/40-web-workers/project.json new file mode 100644 index 000000000..99cb6756a --- /dev/null +++ b/apps/performance/40-web-workers/project.json @@ -0,0 +1,70 @@ +{ + "name": "performance-web-workers", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/40-web-workers/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/40-web-workers", + "index": "apps/performance/40-web-workers/src/index.html", + "browser": "apps/performance/40-web-workers/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/40-web-workers/tsconfig.app.json", + "assets": [ + "apps/performance/40-web-workers/src/favicon.ico", + "apps/performance/40-web-workers/src/assets" + ], + "styles": ["apps/performance/40-web-workers/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "performance-web-workers:build:production" + }, + "development": { + "buildTarget": "performance-web-workers:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "performance-web-workers:build" + } + } + } +} diff --git a/apps/performance/40-web-workers/src/app/app.component.ts b/apps/performance/40-web-workers/src/app/app.component.ts new file mode 100644 index 000000000..da63f1012 --- /dev/null +++ b/apps/performance/40-web-workers/src/app/app.component.ts @@ -0,0 +1,30 @@ +import { Component, inject } from '@angular/core'; +import { HeavyCalculationService } from './heavy-calculation.service'; +import { UnknownPersonComponent } from './unknown-person/unknown-person.component'; + +@Component({ + imports: [UnknownPersonComponent], + providers: [HeavyCalculationService], + selector: 'app-root', + template: ` + + +
Progress: {{ loadingPercentage() }}%
+ `, + host: { + class: `flex flex-col h-screen w-screen bg-[#1f75c0]`, + }, +}) +export class AppComponent { + private heavyCalculationService = inject(HeavyCalculationService); + + readonly loadingPercentage = this.heavyCalculationService.loadingPercentage; + + discover() { + this.heavyCalculationService.startLoading(); + } +} diff --git a/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts b/apps/performance/40-web-workers/src/app/heavy-calculation.service.ts similarity index 100% rename from apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts rename to apps/performance/40-web-workers/src/app/heavy-calculation.service.ts diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css b/apps/performance/40-web-workers/src/app/unknown-person/unknown-person.component.css similarity index 100% rename from apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css rename to apps/performance/40-web-workers/src/app/unknown-person/unknown-person.component.css diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts b/apps/performance/40-web-workers/src/app/unknown-person/unknown-person.component.ts similarity index 82% rename from apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts rename to apps/performance/40-web-workers/src/app/unknown-person/unknown-person.component.ts index c230a4cec..5a0d4bd96 100644 --- a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts +++ b/apps/performance/40-web-workers/src/app/unknown-person/unknown-person.component.ts @@ -1,12 +1,12 @@ -import { Component, Input } from '@angular/core'; +import { Component, input } from '@angular/core'; + @Component({ selector: 'unknown-person', - standalone: true, template: `
- @if (step !== 100) { + [style.height.%]="100 - step()"> + @if (step() !== 100) {
Who is here? @@ -31,5 +31,5 @@ import { Component, Input } from '@angular/core'; styleUrls: [`unknown-person.component.css`], }) export class UnknownPersonComponent { - @Input({ required: true }) step!: number; + step = input.required(); } diff --git a/apps/performance/memoized/src/assets/.gitkeep b/apps/performance/40-web-workers/src/assets/.gitkeep similarity index 100% rename from apps/performance/memoized/src/assets/.gitkeep rename to apps/performance/40-web-workers/src/assets/.gitkeep diff --git a/apps/rxjs/pipe-bug/src/favicon.ico b/apps/performance/40-web-workers/src/favicon.ico similarity index 100% rename from apps/rxjs/pipe-bug/src/favicon.ico rename to apps/performance/40-web-workers/src/favicon.ico diff --git a/apps/performance/40-web-workers/src/index.html b/apps/performance/40-web-workers/src/index.html new file mode 100644 index 000000000..fa0cf99ae --- /dev/null +++ b/apps/performance/40-web-workers/src/index.html @@ -0,0 +1,13 @@ + + + + + performance-web-worker + + + + + + + + diff --git a/apps/performance/40-web-workers/src/main.ts b/apps/performance/40-web-workers/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/performance/40-web-workers/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/performance/40-web-workers/src/styles.scss b/apps/performance/40-web-workers/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/performance/40-web-workers/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/testing/modal/tailwind.config.js b/apps/performance/40-web-workers/tailwind.config.js similarity index 100% rename from apps/testing/modal/tailwind.config.js rename to apps/performance/40-web-workers/tailwind.config.js diff --git a/apps/performance/40-web-workers/tsconfig.app.json b/apps/performance/40-web-workers/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/performance/40-web-workers/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/performance/memoized/tsconfig.editor.json b/apps/performance/40-web-workers/tsconfig.editor.json similarity index 100% rename from apps/performance/memoized/tsconfig.editor.json rename to apps/performance/40-web-workers/tsconfig.editor.json diff --git a/apps/performance/40-web-workers/tsconfig.json b/apps/performance/40-web-workers/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/performance/40-web-workers/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/christmas-web-worker/README.md b/apps/performance/christmas-web-worker/README.md deleted file mode 100644 index 6da93949a..000000000 --- a/apps/performance/christmas-web-worker/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Web workers - -> Author: Thomas Laforge - -### Run Application - -```bash -npx nx serve performance-christmas-web-worker -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/40-christmas-web-worker/). diff --git a/apps/performance/christmas-web-worker/project.json b/apps/performance/christmas-web-worker/project.json deleted file mode 100644 index 13b7edd6b..000000000 --- a/apps/performance/christmas-web-worker/project.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "performance-christmas-web-worker", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/performance/christmas-web-worker/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/christmas-web-worker", - "index": "apps/performance/christmas-web-worker/src/index.html", - "browser": "apps/performance/christmas-web-worker/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/christmas-web-worker/tsconfig.app.json", - "assets": [ - "apps/performance/christmas-web-worker/src/favicon.ico", - "apps/performance/christmas-web-worker/src/assets" - ], - "styles": ["apps/performance/christmas-web-worker/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-christmas-web-worker:build:production" - }, - "development": { - "buildTarget": "performance-christmas-web-worker:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "performance-christmas-web-worker:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/performance/christmas-web-worker/src/app/app.component.ts b/apps/performance/christmas-web-worker/src/app/app.component.ts deleted file mode 100644 index 6b9846b13..000000000 --- a/apps/performance/christmas-web-worker/src/app/app.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component, inject } from '@angular/core'; -import { HeavyCalculationService } from './heavy-calculation.service'; -import { UnknownPersonComponent } from './unknown-person/unknown-person.component'; - -@Component({ - standalone: true, - imports: [CommonModule, UnknownPersonComponent], - providers: [HeavyCalculationService], - selector: 'app-root', - template: ` - - -
Progress: {{ loadingPercentage() }}%
- `, - host: { - class: `flex flex-col h-screen w-screen bg-[#1f75c0]`, - }, -}) -export class AppComponent { - private heavyCalculationService = inject(HeavyCalculationService); - - readonly loadingPercentage = this.heavyCalculationService.loadingPercentage; - - discover() { - this.heavyCalculationService.startLoading(); - } -} diff --git a/apps/performance/christmas-web-worker/src/index.html b/apps/performance/christmas-web-worker/src/index.html deleted file mode 100644 index 4ca378971..000000000 --- a/apps/performance/christmas-web-worker/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - performance-christmas-web-worker - - - - - - - - diff --git a/apps/performance/christmas-web-worker/src/main.ts b/apps/performance/christmas-web-worker/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/performance/christmas-web-worker/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/performance/christmas-web-worker/tsconfig.app.json b/apps/performance/christmas-web-worker/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/christmas-web-worker/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/christmas-web-worker/tsconfig.json b/apps/performance/christmas-web-worker/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/performance/christmas-web-worker/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/default-onpush/README.md b/apps/performance/default-onpush/README.md deleted file mode 100644 index 29d7696ff..000000000 --- a/apps/performance/default-onpush/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Default vs OnPush - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve performance-default-onpush -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/34-default-onpush/). diff --git a/apps/performance/default-onpush/project.json b/apps/performance/default-onpush/project.json deleted file mode 100644 index 14faaabbd..000000000 --- a/apps/performance/default-onpush/project.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "performance-default-onpush", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/performance/default-onpush/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/default-onpush", - "index": "apps/performance/default-onpush/src/index.html", - "main": "apps/performance/default-onpush/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/default-onpush/tsconfig.app.json", - "assets": [ - "apps/performance/default-onpush/src/favicon.ico", - "apps/performance/default-onpush/src/assets" - ], - "styles": [ - "apps/performance/default-onpush/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-default-onpush:build:production" - }, - "development": { - "buildTarget": "performance-default-onpush:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "performance-default-onpush:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/performance/default-onpush/src/app/app.component.ts b/apps/performance/default-onpush/src/app/app.component.ts deleted file mode 100644 index 1eab3c839..000000000 --- a/apps/performance/default-onpush/src/app/app.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component } from '@angular/core'; -import { randFirstName } from '@ngneat/falso'; -import { PersonListComponent } from './person-list.component'; -import { RandomComponent } from './random.component'; - -@Component({ - standalone: true, - imports: [PersonListComponent, RandomComponent], - selector: 'app-root', - template: ` - - -
- - -
- `, -}) -export class AppComponent { - girlList = randFirstName({ gender: 'female', length: 10 }); - boyList = randFirstName({ gender: 'male', length: 10 }); -} diff --git a/apps/performance/default-onpush/src/app/person-list.component.ts b/apps/performance/default-onpush/src/app/person-list.component.ts deleted file mode 100644 index 04574d5c1..000000000 --- a/apps/performance/default-onpush/src/app/person-list.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { CDFlashingDirective } from '@angular-challenges/shared/directives'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { MatChipsModule } from '@angular/material/chips'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatListModule } from '@angular/material/list'; - -@Component({ - selector: 'app-person-list', - standalone: true, - imports: [ - CommonModule, - FormsModule, - MatListModule, - MatFormFieldModule, - MatInputModule, - MatChipsModule, - CDFlashingDirective, - ], - template: ` -

- {{ title | titlecase }} -

- - - - - - -
Empty list
- -
-

- {{ name }} -

-
-
- -
- `, - host: { - class: 'w-full flex flex-col items-center', - }, -}) -export class PersonListComponent { - @Input() names: string[] = []; - @Input() title = ''; - - label = ''; - - handleKey(event: KeyboardEvent) { - if (event.key === 'Enter') { - this.names?.unshift(this.label); - this.label = ''; - } - } -} diff --git a/apps/performance/default-onpush/src/index.html b/apps/performance/default-onpush/src/index.html deleted file mode 100644 index eecd767f7..000000000 --- a/apps/performance/default-onpush/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Default OnPush - - - - - - - - diff --git a/apps/performance/default-onpush/src/main.ts b/apps/performance/default-onpush/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/performance/default-onpush/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/performance/default-onpush/tsconfig.app.json b/apps/performance/default-onpush/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/default-onpush/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/default-onpush/tsconfig.json b/apps/performance/default-onpush/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/performance/default-onpush/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/memoized/README.md b/apps/performance/memoized/README.md deleted file mode 100644 index 520efb1f1..000000000 --- a/apps/performance/memoized/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Memoization - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve performance-memoized -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/35-memoize/). diff --git a/apps/performance/memoized/project.json b/apps/performance/memoized/project.json deleted file mode 100644 index fff792d6a..000000000 --- a/apps/performance/memoized/project.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "performance-memoized", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/performance/memoized/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/memoized", - "index": "apps/performance/memoized/src/index.html", - "main": "apps/performance/memoized/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/memoized/tsconfig.app.json", - "assets": [ - "apps/performance/memoized/src/favicon.ico", - "apps/performance/memoized/src/assets" - ], - "styles": [ - "apps/performance/memoized/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-memoized:build:production" - }, - "development": { - "buildTarget": "performance-memoized:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "performance-memoized:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/performance/memoized/src/app/app.component.ts b/apps/performance/memoized/src/app/app.component.ts deleted file mode 100644 index 4b24fced0..000000000 --- a/apps/performance/memoized/src/app/app.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NgIf } from '@angular/common'; -import { Component } from '@angular/core'; -import { generateList } from './generateList'; -import { PersonListComponent } from './person-list.component'; - -@Component({ - standalone: true, - imports: [PersonListComponent, NgIf], - selector: 'app-root', - template: ` -

Performance is key!!

- - - - `, -}) -export class AppComponent { - persons = generateList(); - loadList = false; -} diff --git a/apps/performance/memoized/src/app/person-list.component.ts b/apps/performance/memoized/src/app/person-list.component.ts deleted file mode 100644 index 4a425d4f2..000000000 --- a/apps/performance/memoized/src/app/person-list.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { MatChipsModule } from '@angular/material/chips'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatListModule } from '@angular/material/list'; -import { Person } from './person.model'; - -const fibonacci = (num: number): number => { - if (num === 1 || num === 2) { - return 1; - } - return fibonacci(num - 1) + fibonacci(num - 2); -}; - -@Component({ - selector: 'app-person-list', - standalone: true, - imports: [ - CommonModule, - FormsModule, - MatListModule, - MatFormFieldModule, - MatInputModule, - MatChipsModule, - ], - template: ` -

- {{ title | titlecase }} -

- - - - - - - -
-

{{ person.name }}

- {{ calculate(person.fib) }} -
-
-
- `, - host: { - class: 'w-full flex flex-col items-center', - }, -}) -export class PersonListComponent { - @Input() persons: Person[] = []; - @Input() title = ''; - - label = ''; - - calculate(num: number) { - return fibonacci(num); - } -} diff --git a/apps/performance/memoized/src/index.html b/apps/performance/memoized/src/index.html deleted file mode 100644 index 1c07d985d..000000000 --- a/apps/performance/memoized/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - performance-memoized - - - - - - - - diff --git a/apps/performance/memoized/src/main.ts b/apps/performance/memoized/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/performance/memoized/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/performance/memoized/tsconfig.app.json b/apps/performance/memoized/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/memoized/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/memoized/tsconfig.json b/apps/performance/memoized/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/performance/memoized/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/ngfor-biglist/README.md b/apps/performance/ngfor-biglist/README.md deleted file mode 100644 index 4d164f0c9..000000000 --- a/apps/performance/ngfor-biglist/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# NgFor optimize big list - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve performance-ngfor-biglist -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/37-ngfor-biglist/). diff --git a/apps/performance/ngfor-biglist/project.json b/apps/performance/ngfor-biglist/project.json deleted file mode 100644 index f6701da1b..000000000 --- a/apps/performance/ngfor-biglist/project.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "performance-ngfor-biglist", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/performance/ngfor-biglist/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/ngfor-biglist", - "index": "apps/performance/ngfor-biglist/src/index.html", - "main": "apps/performance/ngfor-biglist/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/ngfor-biglist/tsconfig.app.json", - "assets": [ - "apps/performance/ngfor-biglist/src/favicon.ico", - "apps/performance/ngfor-biglist/src/assets" - ], - "styles": [ - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "apps/performance/ngfor-biglist/src/styles.scss" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-ngfor-biglist:build:production" - }, - "development": { - "buildTarget": "performance-ngfor-biglist:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "performance-ngfor-biglist:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/performance/ngfor-biglist/src/app/app.component.ts b/apps/performance/ngfor-biglist/src/app/app.component.ts deleted file mode 100644 index 9c26149b2..000000000 --- a/apps/performance/ngfor-biglist/src/app/app.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NgIf } from '@angular/common'; -import { Component, signal } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { generateList } from './generateList'; -import { PersonService } from './list.service'; -import { PersonListComponent } from './person-list.component'; - -@Component({ - standalone: true, - imports: [ - NgIf, - PersonListComponent, - FormsModule, - MatFormFieldModule, - MatInputModule, - ], - providers: [PersonService], - selector: 'app-root', - template: ` - - - - `, - host: { - class: 'flex items-center flex-col gap-5', - }, -}) -export class AppComponent { - readonly persons = signal(generateList()); - readonly loadList = signal(false); - - label = ''; -} diff --git a/apps/performance/ngfor-biglist/src/app/person-list.component.ts b/apps/performance/ngfor-biglist/src/app/person-list.component.ts deleted file mode 100644 index 4d438e664..000000000 --- a/apps/performance/ngfor-biglist/src/app/person-list.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; - -import { NgForTrackByModule } from '@angular-challenges/shared/directives'; -import { CommonModule } from '@angular/common'; -import { Person } from './person.model'; - -@Component({ - selector: 'app-person-list', - standalone: true, - imports: [CommonModule, NgForTrackByModule], - template: ` -
-
-
-

{{ person.name }}

-

{{ person.email }}

-
-
-
- `, - host: { - class: 'w-full flex flex-col', - }, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PersonListComponent { - @Input() persons: Person[] = []; -} diff --git a/apps/performance/ngfor-biglist/src/index.html b/apps/performance/ngfor-biglist/src/index.html deleted file mode 100644 index 1b058276a..000000000 --- a/apps/performance/ngfor-biglist/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - performance-ngfor-biglist - - - - - - - - diff --git a/apps/performance/ngfor-biglist/src/main.ts b/apps/performance/ngfor-biglist/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/performance/ngfor-biglist/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/performance/ngfor-biglist/tsconfig.app.json b/apps/performance/ngfor-biglist/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/ngfor-biglist/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/ngfor-biglist/tsconfig.json b/apps/performance/ngfor-biglist/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/performance/ngfor-biglist/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/ngfor-optimize/README.md b/apps/performance/ngfor-optimize/README.md deleted file mode 100644 index 1e9b2f833..000000000 --- a/apps/performance/ngfor-optimize/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# NgFor Optimization - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve performance-ngfor-optimize -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/36-ngfor-optimize/). diff --git a/apps/performance/ngfor-optimize/jest.config.ts b/apps/performance/ngfor-optimize/jest.config.ts deleted file mode 100644 index 5b2ccaee0..000000000 --- a/apps/performance/ngfor-optimize/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'performance-ngfor-optimize', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/performance/ngfor-optimize', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/performance/ngfor-optimize/project.json b/apps/performance/ngfor-optimize/project.json deleted file mode 100644 index 20ac3a630..000000000 --- a/apps/performance/ngfor-optimize/project.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "name": "performance-ngfor-optimize", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/performance/ngfor-optimize/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/ngfor-optimize", - "index": "apps/performance/ngfor-optimize/src/index.html", - "main": "apps/performance/ngfor-optimize/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/ngfor-optimize/tsconfig.app.json", - "assets": [ - "apps/performance/ngfor-optimize/src/favicon.ico", - "apps/performance/ngfor-optimize/src/assets" - ], - "styles": [ - "apps/performance/ngfor-optimize/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-ngfor-optimize:build:production" - }, - "development": { - "buildTarget": "performance-ngfor-optimize:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "performance-ngfor-optimize:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/performance/ngfor-optimize/jest.config.ts" - } - } - } -} diff --git a/apps/performance/ngfor-optimize/src/app/app.component.ts b/apps/performance/ngfor-optimize/src/app/app.component.ts deleted file mode 100644 index fb9e98516..000000000 --- a/apps/performance/ngfor-optimize/src/app/app.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component, OnInit, inject } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { PersonService } from './list.service'; -import { PersonListComponent } from './person-list.component'; - -@Component({ - standalone: true, - imports: [ - PersonListComponent, - FormsModule, - MatFormFieldModule, - MatInputModule, - ], - providers: [PersonService], - selector: 'app-root', - template: ` -

- List of Persons -

- - - - - - - `, - host: { - class: 'flex items-center flex-col gap-5', - }, -}) -export class AppComponent implements OnInit { - readonly personService = inject(PersonService); - readonly persons = this.personService.persons; - - label = ''; - - ngOnInit(): void { - this.personService.loadPersons(); - } - - handleKey(event: any) { - if (event.keyCode === 13) { - this.personService.addPerson(this.label); - this.label = ''; - } - } -} diff --git a/apps/performance/ngfor-optimize/src/app/person-list.component.ts b/apps/performance/ngfor-optimize/src/app/person-list.component.ts deleted file mode 100644 index ca04956d0..000000000 --- a/apps/performance/ngfor-optimize/src/app/person-list.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -import { CommonModule } from '@angular/common'; -import { Person } from './person.model'; - -@Component({ - selector: 'app-person-list', - standalone: true, - imports: [CommonModule], - template: ` -
-

{{ person.name }}

-
- - -
-
- `, - host: { - class: 'w-full flex flex-col', - }, -}) -export class PersonListComponent { - @Input() persons: Person[] = []; - @Output() delete = new EventEmitter(); - @Output() update = new EventEmitter(); -} diff --git a/apps/performance/ngfor-optimize/src/index.html b/apps/performance/ngfor-optimize/src/index.html deleted file mode 100644 index e5b79903e..000000000 --- a/apps/performance/ngfor-optimize/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - performance-ngfor-optimize - - - - - - - - diff --git a/apps/performance/ngfor-optimize/src/main.ts b/apps/performance/ngfor-optimize/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/performance/ngfor-optimize/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/performance/ngfor-optimize/src/test-setup.ts b/apps/performance/ngfor-optimize/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/performance/ngfor-optimize/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/performance/ngfor-optimize/tsconfig.app.json b/apps/performance/ngfor-optimize/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/ngfor-optimize/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/ngfor-optimize/tsconfig.json b/apps/performance/ngfor-optimize/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/performance/ngfor-optimize/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/ngfor-optimize/tsconfig.spec.json b/apps/performance/ngfor-optimize/tsconfig.spec.json deleted file mode 100644 index 1a4817a7d..000000000 --- a/apps/performance/ngfor-optimize/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/performance/scroll-cd/README.md b/apps/performance/scroll-cd/README.md deleted file mode 100644 index dc0c31301..000000000 --- a/apps/performance/scroll-cd/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Optimize Change Detection - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve performance-scroll-cd -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/12-performance-scroll-cd/). diff --git a/apps/performance/scroll-cd/jest.config.ts b/apps/performance/scroll-cd/jest.config.ts deleted file mode 100644 index 4c9105010..000000000 --- a/apps/performance/scroll-cd/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'performance-scroll-cd', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/apps/performance/scroll-cd', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/performance/scroll-cd/project.json b/apps/performance/scroll-cd/project.json deleted file mode 100644 index fb455b73e..000000000 --- a/apps/performance/scroll-cd/project.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "performance-scroll-cd", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/performance/scroll-cd/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/performance/scroll-cd", - "index": "apps/performance/scroll-cd/src/index.html", - "main": "apps/performance/scroll-cd/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/performance/scroll-cd/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/performance/scroll-cd/src/favicon.ico", - "apps/performance/scroll-cd/src/assets" - ], - "styles": ["apps/performance/scroll-cd/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "performance-scroll-cd:build:production" - }, - "development": { - "buildTarget": "performance-scroll-cd:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "performance-scroll-cd:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/performance/scroll-cd/jest.config.ts" - } - } - }, - "tags": [] -} diff --git a/apps/performance/scroll-cd/src/app/app.component.ts b/apps/performance/scroll-cd/src/app/app.component.ts deleted file mode 100644 index e75ef991e..000000000 --- a/apps/performance/scroll-cd/src/app/app.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { AsyncPipe, NgIf } from '@angular/common'; -import { Component, HostListener } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; - -@Component({ - standalone: true, - imports: [NgIf, AsyncPipe], - selector: 'app-root', - template: ` -
Top
-
Middle
-
Bottom
- - `, - styles: [ - ` - :host { - height: 1500px; - display: flex; - flex-direction: column; - justify-content: space-between; - - button { - position: fixed; - bottom: 1rem; - left: 1rem; - z-index: 1; - padding: 1rem; - } - } - `, - ], -}) -export class AppComponent { - title = 'scroll-cd'; - - private displayButtonSubject = new BehaviorSubject(false); - displayButton$ = this.displayButtonSubject.asObservable(); - - @HostListener('window:scroll', ['$event']) - onScroll() { - const pos = window.pageYOffset; - this.displayButtonSubject.next(pos > 50); - } - - goToTop() { - window.scroll({ - top: 0, - left: 0, - behavior: 'smooth', - }); - } -} diff --git a/apps/performance/scroll-cd/src/index.html b/apps/performance/scroll-cd/src/index.html deleted file mode 100644 index 1d22cac27..000000000 --- a/apps/performance/scroll-cd/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - ScrollCd - - - - - - - - diff --git a/apps/performance/scroll-cd/src/main.ts b/apps/performance/scroll-cd/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/performance/scroll-cd/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/performance/scroll-cd/src/test-setup.ts b/apps/performance/scroll-cd/src/test-setup.ts deleted file mode 100644 index 1100b3e8a..000000000 --- a/apps/performance/scroll-cd/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular/setup-jest'; diff --git a/apps/performance/scroll-cd/tsconfig.app.json b/apps/performance/scroll-cd/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/performance/scroll-cd/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/performance/scroll-cd/tsconfig.json b/apps/performance/scroll-cd/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/performance/scroll-cd/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/performance/scroll-cd/tsconfig.spec.json b/apps/performance/scroll-cd/tsconfig.spec.json deleted file mode 100644 index ca14cc622..000000000 --- a/apps/performance/scroll-cd/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/rxjs/11-high-order-operator-bug/.eslintrc.json b/apps/rxjs/11-high-order-operator-bug/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/rxjs/11-high-order-operator-bug/README.md b/apps/rxjs/11-high-order-operator-bug/README.md new file mode 100644 index 000000000..5a4fa5512 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/README.md @@ -0,0 +1,13 @@ +# High Order Operator Bug + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve rxjs-high-order-operator-bug +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/rxjs/11-bug-chaining-operator/). diff --git a/apps/rxjs/11-high-order-operator-bug/project.json b/apps/rxjs/11-high-order-operator-bug/project.json new file mode 100644 index 000000000..2ab592032 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/project.json @@ -0,0 +1,74 @@ +{ + "name": "rxjs-high-order-operator-bug", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/rxjs/11-high-order-operator-bug/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/rxjs/11-high-order-operator-bug", + "index": "apps/rxjs/11-high-order-operator-bug/src/index.html", + "main": "apps/rxjs/11-high-order-operator-bug/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/rxjs/11-high-order-operator-bug/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/rxjs/11-high-order-operator-bug/src/favicon.ico", + "apps/rxjs/11-high-order-operator-bug/src/assets" + ], + "styles": ["apps/rxjs/11-high-order-operator-bug/src/styles.scss"], + "scripts": [], + "allowedCommonJsDependencies": ["seedrandom"] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "rxjs-high-order-operator-bug:build:production" + }, + "development": { + "buildTarget": "rxjs-high-order-operator-bug:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "rxjs-high-order-operator-bug:build" + } + } + } +} diff --git a/apps/rxjs/11-high-order-operator-bug/src/app/app.component.ts b/apps/rxjs/11-high-order-operator-bug/src/app/app.component.ts new file mode 100644 index 000000000..fb80fb2b6 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/src/app/app.component.ts @@ -0,0 +1,52 @@ +/* eslint-disable @angular-eslint/component-selector */ +import { Component, inject, input, signal } from '@angular/core'; +import { take } from 'rxjs'; +import { AppService } from './app.service'; +import { TopicType } from './localDB.service'; + +@Component({ + selector: 'button-delete-topic', + template: ` + +
{{ message() }}
+ `, +}) +export class ButtonDeleteComponent { + readonly topic = input.required(); + + message = signal(''); + + private service = inject(AppService); + + deleteTopic() { + this.service + .deleteOldTopics(this.topic()) + .pipe(take(1)) + .subscribe((result) => + this.message.set( + result + ? `All ${this.topic()} have been deleted` + : `Error: deletion of some ${this.topic()} failed`, + ), + ); + } +} + +@Component({ + imports: [ButtonDeleteComponent], + selector: 'app-root', + template: ` + @for (info of allInfo(); track info.id) { +
{{ info.id }} - {{ info.topic }}
+ } + + Delete Food + Delete Sport + Delete Book + `, +}) +export class AppComponent { + private service = inject(AppService); + + allInfo = this.service.getAllInfo; +} diff --git a/apps/rxjs/11-high-order-operator-bug/src/app/app.service.ts b/apps/rxjs/11-high-order-operator-bug/src/app/app.service.ts new file mode 100644 index 000000000..df2269a89 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/src/app/app.service.ts @@ -0,0 +1,19 @@ +import { inject, Injectable } from '@angular/core'; +import { merge, Observable, of } from 'rxjs'; +import { LocalDBService, TopicType } from './localDB.service'; + +@Injectable({ providedIn: 'root' }) +export class AppService { + private dbService = inject(LocalDBService); + + getAllInfo = this.dbService.infos; + + deleteOldTopics(type: TopicType): Observable { + const infoByType = this.dbService.searchByType(type); + return infoByType.length > 0 + ? infoByType + .map((t) => this.dbService.deleteOneTopic(t.id)) + .reduce((acc, curr) => merge(acc, curr), of(true)) + : of(true); + } +} diff --git a/apps/rxjs/11-high-order-operator-bug/src/app/localDB.service.ts b/apps/rxjs/11-high-order-operator-bug/src/app/localDB.service.ts new file mode 100644 index 000000000..5a035e087 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/src/app/localDB.service.ts @@ -0,0 +1,53 @@ +/* eslint-disable @typescript-eslint/member-ordering */ +import { randomError } from '@angular-challenges/shared/utils'; +import { computed, Injectable, signal } from '@angular/core'; +import { of } from 'rxjs'; + +export type TopicType = 'food' | 'book' | 'sport'; + +interface Info { + id: number; + topic: TopicType; +} + +interface DBState { + infos: Info[]; +} + +const initialState: DBState = { + infos: [ + { id: 1, topic: 'book' }, + { id: 2, topic: 'book' }, + { id: 3, topic: 'book' }, + { id: 4, topic: 'book' }, + { id: 5, topic: 'food' }, + { id: 6, topic: 'food' }, + { id: 7, topic: 'book' }, + { id: 8, topic: 'book' }, + { id: 9, topic: 'book' }, + { id: 10, topic: 'sport' }, + ], +}; + +@Injectable({ providedIn: 'root' }) +export class LocalDBService { + private state = signal(initialState); + + infos = computed(() => this.state().infos); + + searchByType = (type: TopicType) => + this.infos().filter((i) => i.topic === type); + + deleteOne = (id: number) => { + this.state.set({ infos: this.state().infos.filter((i) => i.id !== id) }); + }; + + deleteOneTopic = (id: number) => + randomError({ + success: () => { + this.deleteOne(id); + return of(true); + }, + error: () => of(false), + }); +} diff --git a/apps/performance/ngfor-biglist/src/assets/.gitkeep b/apps/rxjs/11-high-order-operator-bug/src/assets/.gitkeep similarity index 100% rename from apps/performance/ngfor-biglist/src/assets/.gitkeep rename to apps/rxjs/11-high-order-operator-bug/src/assets/.gitkeep diff --git a/apps/rxjs/race-condition/src/favicon.ico b/apps/rxjs/11-high-order-operator-bug/src/favicon.ico similarity index 100% rename from apps/rxjs/race-condition/src/favicon.ico rename to apps/rxjs/11-high-order-operator-bug/src/favicon.ico diff --git a/apps/rxjs/11-high-order-operator-bug/src/index.html b/apps/rxjs/11-high-order-operator-bug/src/index.html new file mode 100644 index 000000000..148a16280 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/src/index.html @@ -0,0 +1,13 @@ + + + + + rxjs-high-order-operator-bug + + + + + + + + diff --git a/apps/rxjs/11-high-order-operator-bug/src/main.ts b/apps/rxjs/11-high-order-operator-bug/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/ngrx/notification/src/styles.scss b/apps/rxjs/11-high-order-operator-bug/src/styles.scss similarity index 100% rename from apps/ngrx/notification/src/styles.scss rename to apps/rxjs/11-high-order-operator-bug/src/styles.scss diff --git a/apps/rxjs/11-high-order-operator-bug/tsconfig.app.json b/apps/rxjs/11-high-order-operator-bug/tsconfig.app.json new file mode 100644 index 000000000..44ab2b22f --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/apps/angular/pipe-intermediate/tsconfig.editor.json b/apps/rxjs/11-high-order-operator-bug/tsconfig.editor.json similarity index 100% rename from apps/angular/pipe-intermediate/tsconfig.editor.json rename to apps/rxjs/11-high-order-operator-bug/tsconfig.editor.json diff --git a/apps/rxjs/11-high-order-operator-bug/tsconfig.json b/apps/rxjs/11-high-order-operator-bug/tsconfig.json new file mode 100644 index 000000000..64afff1f8 --- /dev/null +++ b/apps/rxjs/11-high-order-operator-bug/tsconfig.json @@ -0,0 +1,32 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/scroll-cd/.eslintrc.json b/apps/rxjs/14-race-condition/.eslintrc.json similarity index 100% rename from apps/performance/scroll-cd/.eslintrc.json rename to apps/rxjs/14-race-condition/.eslintrc.json diff --git a/apps/rxjs/race-condition/README.md b/apps/rxjs/14-race-condition/README.md similarity index 100% rename from apps/rxjs/race-condition/README.md rename to apps/rxjs/14-race-condition/README.md diff --git a/apps/rxjs/14-race-condition/cypress.config.ts b/apps/rxjs/14-race-condition/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/rxjs/14-race-condition/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/rxjs/race-condition/cypress/fixtures/example.json b/apps/rxjs/14-race-condition/cypress/fixtures/example.json similarity index 100% rename from apps/rxjs/race-condition/cypress/fixtures/example.json rename to apps/rxjs/14-race-condition/cypress/fixtures/example.json diff --git a/apps/rxjs/race-condition/cypress/support/commands.ts b/apps/rxjs/14-race-condition/cypress/support/commands.ts similarity index 100% rename from apps/rxjs/race-condition/cypress/support/commands.ts rename to apps/rxjs/14-race-condition/cypress/support/commands.ts diff --git a/apps/rxjs/race-condition/cypress/support/component-index.html b/apps/rxjs/14-race-condition/cypress/support/component-index.html similarity index 100% rename from apps/rxjs/race-condition/cypress/support/component-index.html rename to apps/rxjs/14-race-condition/cypress/support/component-index.html diff --git a/apps/rxjs/race-condition/cypress/support/component.ts b/apps/rxjs/14-race-condition/cypress/support/component.ts similarity index 100% rename from apps/rxjs/race-condition/cypress/support/component.ts rename to apps/rxjs/14-race-condition/cypress/support/component.ts diff --git a/apps/rxjs/race-condition/cypress/tsconfig.json b/apps/rxjs/14-race-condition/cypress/tsconfig.json similarity index 100% rename from apps/rxjs/race-condition/cypress/tsconfig.json rename to apps/rxjs/14-race-condition/cypress/tsconfig.json diff --git a/apps/rxjs/14-race-condition/jest.config.ts b/apps/rxjs/14-race-condition/jest.config.ts new file mode 100644 index 000000000..ec9bd85b8 --- /dev/null +++ b/apps/rxjs/14-race-condition/jest.config.ts @@ -0,0 +1,23 @@ +/* eslint-disable */ +module.exports = { + displayName: 'rxjs-race-condition', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: {}, + coverageDirectory: '../../../coverage/apps/rxjs/14-race-condition', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/rxjs/14-race-condition/project.json b/apps/rxjs/14-race-condition/project.json new file mode 100644 index 000000000..c5191f620 --- /dev/null +++ b/apps/rxjs/14-race-condition/project.json @@ -0,0 +1,93 @@ +{ + "name": "rxjs-race-condition", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/rxjs/14-race-condition/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/rxjs/14-race-condition", + "index": "apps/rxjs/14-race-condition/src/index.html", + "main": "apps/rxjs/14-race-condition/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/rxjs/14-race-condition/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/rxjs/14-race-condition/src/favicon.ico", + "apps/rxjs/14-race-condition/src/assets" + ], + "styles": ["apps/rxjs/14-race-condition/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "rxjs-race-condition:build:production" + }, + "development": { + "buildTarget": "rxjs-race-condition:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "rxjs-race-condition:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/rxjs/14-race-condition/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-router:build" + } + } + } +} diff --git a/apps/rxjs/race-condition/src/app/app.component.cy.ts b/apps/rxjs/14-race-condition/src/app/app.component.cy.ts similarity index 100% rename from apps/rxjs/race-condition/src/app/app.component.cy.ts rename to apps/rxjs/14-race-condition/src/app/app.component.cy.ts diff --git a/apps/rxjs/14-race-condition/src/app/app.component.ts b/apps/rxjs/14-race-condition/src/app/app.component.ts new file mode 100644 index 000000000..a23c31f08 --- /dev/null +++ b/apps/rxjs/14-race-condition/src/app/app.component.ts @@ -0,0 +1,39 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + OnInit, +} from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { take } from 'rxjs'; +import { TopicModalComponent } from './topic-dialog.component'; +import { TopicService, TopicType } from './topic.service'; + +@Component({ + selector: 'app-root', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent implements OnInit { + title = 'rxjs-race-condition'; + dialog = inject(MatDialog); + topicService = inject(TopicService); + topics: TopicType[] = []; + + ngOnInit(): void { + this.topicService + .fakeGetHttpTopic() + .pipe(take(1)) + .subscribe((topics) => (this.topics = topics)); + } + + openTopicModal() { + this.dialog.open(TopicModalComponent, { + data: { + topics: this.topics, + }, + }); + } +} diff --git a/apps/rxjs/race-condition/src/app/app.config.ts b/apps/rxjs/14-race-condition/src/app/app.config.ts similarity index 100% rename from apps/rxjs/race-condition/src/app/app.config.ts rename to apps/rxjs/14-race-condition/src/app/app.config.ts diff --git a/apps/rxjs/14-race-condition/src/app/topic-dialog.component.ts b/apps/rxjs/14-race-condition/src/app/topic-dialog.component.ts new file mode 100644 index 000000000..67d8ec29b --- /dev/null +++ b/apps/rxjs/14-race-condition/src/app/topic-dialog.component.ts @@ -0,0 +1,26 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; + +@Component({ + template: ` +

Show all Topics

+
+
    + @for (topic of data.topics; track $index) { +
  • + {{ topic }} +
  • + } +
+
+
+ +
+ `, + imports: [MatDialogModule, MatButtonModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TopicModalComponent { + data = inject(MAT_DIALOG_DATA); +} diff --git a/apps/rxjs/race-condition/src/app/topic.service.ts b/apps/rxjs/14-race-condition/src/app/topic.service.ts similarity index 100% rename from apps/rxjs/race-condition/src/app/topic.service.ts rename to apps/rxjs/14-race-condition/src/app/topic.service.ts diff --git a/apps/performance/ngfor-optimize/src/assets/.gitkeep b/apps/rxjs/14-race-condition/src/assets/.gitkeep similarity index 100% rename from apps/performance/ngfor-optimize/src/assets/.gitkeep rename to apps/rxjs/14-race-condition/src/assets/.gitkeep diff --git a/apps/testing/checkbox/src/favicon.ico b/apps/rxjs/14-race-condition/src/favicon.ico similarity index 100% rename from apps/testing/checkbox/src/favicon.ico rename to apps/rxjs/14-race-condition/src/favicon.ico diff --git a/apps/rxjs/14-race-condition/src/index.html b/apps/rxjs/14-race-condition/src/index.html new file mode 100644 index 000000000..629547b5b --- /dev/null +++ b/apps/rxjs/14-race-condition/src/index.html @@ -0,0 +1,13 @@ + + + + + rxjs-race-condition + + + + + + + + diff --git a/apps/rxjs/14-race-condition/src/main.ts b/apps/rxjs/14-race-condition/src/main.ts new file mode 100644 index 000000000..866d45959 --- /dev/null +++ b/apps/rxjs/14-race-condition/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { appConfig } from './app/app.config'; + +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/rxjs/14-race-condition/src/styles.scss b/apps/rxjs/14-race-condition/src/styles.scss new file mode 100644 index 000000000..215c83eb9 --- /dev/null +++ b/apps/rxjs/14-race-condition/src/styles.scss @@ -0,0 +1,25 @@ +/* You can add global styles to this file, and also import other style files */ + +@use '@angular/material' as mat; + +@include mat.elevation-classes(); +@include mat.app-background(); + +$theme-primary: mat.m2-define-palette(mat.$m2-indigo-palette); +$theme-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); + +$theme-warn: mat.m2-define-palette(mat.$m2-red-palette); + +$theme: mat.m2-define-light-theme( + ( + color: ( + primary: $theme-primary, + accent: $theme-accent, + warn: $theme-warn, + ), + typography: mat.m2-define-typography-config(), + ) +); + +@include mat.dialog-theme($theme); +@include mat.button-theme($theme); diff --git a/apps/rxjs/14-race-condition/src/test-setup.ts b/apps/rxjs/14-race-condition/src/test-setup.ts new file mode 100644 index 000000000..58c511e08 --- /dev/null +++ b/apps/rxjs/14-race-condition/src/test-setup.ts @@ -0,0 +1,3 @@ +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/rxjs/14-race-condition/tsconfig.app.json b/apps/rxjs/14-race-condition/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/rxjs/14-race-condition/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/performance/scroll-cd/tsconfig.editor.json b/apps/rxjs/14-race-condition/tsconfig.editor.json similarity index 100% rename from apps/performance/scroll-cd/tsconfig.editor.json rename to apps/rxjs/14-race-condition/tsconfig.editor.json diff --git a/apps/rxjs/14-race-condition/tsconfig.json b/apps/rxjs/14-race-condition/tsconfig.json new file mode 100644 index 000000000..2316dadd3 --- /dev/null +++ b/apps/rxjs/14-race-condition/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/rxjs/14-race-condition/tsconfig.spec.json b/apps/rxjs/14-race-condition/tsconfig.spec.json new file mode 100644 index 000000000..032d49d7a --- /dev/null +++ b/apps/rxjs/14-race-condition/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/rxjs/catch-error/.eslintrc.json b/apps/rxjs/38-catch-error/.eslintrc.json similarity index 100% rename from apps/rxjs/catch-error/.eslintrc.json rename to apps/rxjs/38-catch-error/.eslintrc.json diff --git a/apps/rxjs/catch-error/README.md b/apps/rxjs/38-catch-error/README.md similarity index 100% rename from apps/rxjs/catch-error/README.md rename to apps/rxjs/38-catch-error/README.md diff --git a/apps/rxjs/38-catch-error/jest.config.ts b/apps/rxjs/38-catch-error/jest.config.ts new file mode 100644 index 000000000..90379aecb --- /dev/null +++ b/apps/rxjs/38-catch-error/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'rxjs-catch-error', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/rxjs/38-catch-error', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/rxjs/38-catch-error/project.json b/apps/rxjs/38-catch-error/project.json new file mode 100644 index 000000000..9c2ad7cb9 --- /dev/null +++ b/apps/rxjs/38-catch-error/project.json @@ -0,0 +1,83 @@ +{ + "name": "rxjs-catch-error", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/rxjs/38-catch-error/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/rxjs/38-catch-error", + "index": "apps/rxjs/38-catch-error/src/index.html", + "main": "apps/rxjs/38-catch-error/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/rxjs/38-catch-error/tsconfig.app.json", + "assets": [ + "apps/rxjs/38-catch-error/src/favicon.ico", + "apps/rxjs/38-catch-error/src/assets" + ], + "styles": ["apps/rxjs/38-catch-error/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "rxjs-catch-error:build:production" + }, + "development": { + "buildTarget": "rxjs-catch-error:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "rxjs-catch-error:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/rxjs/catch-error/src/app/app.component.css b/apps/rxjs/38-catch-error/src/app/app.component.css similarity index 100% rename from apps/rxjs/catch-error/src/app/app.component.css rename to apps/rxjs/38-catch-error/src/app/app.component.css diff --git a/apps/rxjs/catch-error/src/app/app.component.spec.ts b/apps/rxjs/38-catch-error/src/app/app.component.spec.ts similarity index 100% rename from apps/rxjs/catch-error/src/app/app.component.spec.ts rename to apps/rxjs/38-catch-error/src/app/app.component.spec.ts diff --git a/apps/rxjs/38-catch-error/src/app/app.component.ts b/apps/rxjs/38-catch-error/src/app/app.component.ts new file mode 100644 index 000000000..65e177567 --- /dev/null +++ b/apps/rxjs/38-catch-error/src/app/app.component.ts @@ -0,0 +1,60 @@ +import { CommonModule } from '@angular/common'; +import { HttpClient } from '@angular/common/http'; +import { Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { FormsModule } from '@angular/forms'; +import { Subject, concatMap, map } from 'rxjs'; + +@Component({ + imports: [CommonModule, FormsModule], + selector: 'app-root', + template: ` +
+ + possible values: posts, comments, albums, photos, todos, users + +
+
+ + +
+
+ {{ response | json }} +
+ `, + styleUrls: ['./app.component.css'], +}) +export class AppComponent implements OnInit { + submit$ = new Subject(); + input = ''; + response: unknown; + + private destroyRef = inject(DestroyRef); + private http = inject(HttpClient); + + ngOnInit() { + this.submit$ + .pipe( + map(() => this.input), + concatMap((value) => + this.http.get(`https://jsonplaceholder.typicode.com/${value}/1`), + ), + takeUntilDestroyed(this.destroyRef), + ) + .subscribe({ + next: (value) => { + console.log(value); + this.response = value; + }, + error: (error) => { + console.log(error); + this.response = error; + }, + complete: () => console.log('done'), + }); + } +} diff --git a/apps/rxjs/38-catch-error/src/app/app.config.ts b/apps/rxjs/38-catch-error/src/app/app.config.ts new file mode 100644 index 000000000..1c0c9422f --- /dev/null +++ b/apps/rxjs/38-catch-error/src/app/app.config.ts @@ -0,0 +1,6 @@ +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideHttpClient()], +}; diff --git a/apps/performance/scroll-cd/src/assets/.gitkeep b/apps/rxjs/38-catch-error/src/assets/.gitkeep similarity index 100% rename from apps/performance/scroll-cd/src/assets/.gitkeep rename to apps/rxjs/38-catch-error/src/assets/.gitkeep diff --git a/apps/testing/create-harness/src/favicon.ico b/apps/rxjs/38-catch-error/src/favicon.ico similarity index 100% rename from apps/testing/create-harness/src/favicon.ico rename to apps/rxjs/38-catch-error/src/favicon.ico diff --git a/apps/rxjs/catch-error/src/index.html b/apps/rxjs/38-catch-error/src/index.html similarity index 100% rename from apps/rxjs/catch-error/src/index.html rename to apps/rxjs/38-catch-error/src/index.html diff --git a/apps/rxjs/38-catch-error/src/main.ts b/apps/rxjs/38-catch-error/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/rxjs/38-catch-error/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/rxjs/38-catch-error/src/styles.scss b/apps/rxjs/38-catch-error/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/rxjs/38-catch-error/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/rxjs/38-catch-error/src/test-setup.ts b/apps/rxjs/38-catch-error/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/rxjs/38-catch-error/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/table/tailwind.config.js b/apps/rxjs/38-catch-error/tailwind.config.js similarity index 100% rename from apps/testing/table/tailwind.config.js rename to apps/rxjs/38-catch-error/tailwind.config.js diff --git a/apps/rxjs/38-catch-error/tsconfig.app.json b/apps/rxjs/38-catch-error/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/rxjs/38-catch-error/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/rxjs/catch-error/tsconfig.editor.json b/apps/rxjs/38-catch-error/tsconfig.editor.json similarity index 100% rename from apps/rxjs/catch-error/tsconfig.editor.json rename to apps/rxjs/38-catch-error/tsconfig.editor.json diff --git a/apps/rxjs/38-catch-error/tsconfig.json b/apps/rxjs/38-catch-error/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/rxjs/38-catch-error/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/rxjs/38-catch-error/tsconfig.spec.json b/apps/rxjs/38-catch-error/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/rxjs/38-catch-error/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/rxjs/49-hold-to-save-button/.eslintrc.json b/apps/rxjs/49-hold-to-save-button/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/rxjs/49-hold-to-save-button/README.md b/apps/rxjs/49-hold-to-save-button/README.md new file mode 100644 index 000000000..e0d4c012b --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/README.md @@ -0,0 +1,13 @@ +# Hold to send button + +> author: alcaidio + +### Run Application + +```bash +npx nx serve rxjs-hold-to-save-button +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/rxjs/49-hold-to-save-btn/). diff --git a/apps/rxjs/49-hold-to-save-button/jest.config.ts b/apps/rxjs/49-hold-to-save-button/jest.config.ts new file mode 100644 index 000000000..66b7df8a3 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'rxjs-hold-to-save-button', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/rxjs/49-hold-to-save-button', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/rxjs/49-hold-to-save-button/project.json b/apps/rxjs/49-hold-to-save-button/project.json new file mode 100644 index 000000000..f4e2e33c4 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/project.json @@ -0,0 +1,81 @@ +{ + "name": "rxjs-hold-to-save-button", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/rxjs/49-hold-to-save-button/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/rxjs/49-hold-to-save-button", + "index": "apps/rxjs/49-hold-to-save-button/src/index.html", + "browser": "apps/rxjs/49-hold-to-save-button/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/rxjs/49-hold-to-save-button/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/rxjs/49-hold-to-save-button/src/favicon.ico", + "apps/rxjs/49-hold-to-save-button/src/assets" + ], + "styles": ["apps/rxjs/49-hold-to-save-button/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "rxjs-hold-to-save-button:build:production" + }, + "development": { + "buildTarget": "rxjs-hold-to-save-button:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "rxjs-hold-to-save-button:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/rxjs/49-hold-to-save-button/src/app/app.component.ts b/apps/rxjs/49-hold-to-save-button/src/app/app.component.ts new file mode 100644 index 000000000..8f0dbbc70 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/src/app/app.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + imports: [], + selector: 'app-root', + template: ` +
+
+ + + +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + onSend() { + console.log('Save it!'); + } +} diff --git a/apps/angular/simple-animations/src/app/app.config.ts b/apps/rxjs/49-hold-to-save-button/src/app/app.config.ts similarity index 100% rename from apps/angular/simple-animations/src/app/app.config.ts rename to apps/rxjs/49-hold-to-save-button/src/app/app.config.ts diff --git a/apps/rxjs/catch-error/src/assets/.gitkeep b/apps/rxjs/49-hold-to-save-button/src/assets/.gitkeep similarity index 100% rename from apps/rxjs/catch-error/src/assets/.gitkeep rename to apps/rxjs/49-hold-to-save-button/src/assets/.gitkeep diff --git a/apps/testing/harness/src/favicon.ico b/apps/rxjs/49-hold-to-save-button/src/favicon.ico similarity index 100% rename from apps/testing/harness/src/favicon.ico rename to apps/rxjs/49-hold-to-save-button/src/favicon.ico diff --git a/apps/rxjs/49-hold-to-save-button/src/index.html b/apps/rxjs/49-hold-to-save-button/src/index.html new file mode 100644 index 000000000..3f8e222b1 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/src/index.html @@ -0,0 +1,13 @@ + + + + + rxjs-hold-to-save-button + + + + + + + + diff --git a/apps/rxjs/49-hold-to-save-button/src/main.ts b/apps/rxjs/49-hold-to-save-button/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/rxjs/49-hold-to-save-button/src/styles.scss b/apps/rxjs/49-hold-to-save-button/src/styles.scss new file mode 100644 index 000000000..c98dac907 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/src/styles.scss @@ -0,0 +1,14 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +progress { + @apply h-4 w-full rounded-full bg-gray-200; +} +progress::-webkit-progress-bar { + @apply rounded-full bg-gray-200; +} + +progress::-webkit-progress-value { + @apply rounded-full bg-indigo-600; +} diff --git a/apps/rxjs/49-hold-to-save-button/src/test-setup.ts b/apps/rxjs/49-hold-to-save-button/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/todos-list/tailwind.config.js b/apps/rxjs/49-hold-to-save-button/tailwind.config.js similarity index 100% rename from apps/testing/todos-list/tailwind.config.js rename to apps/rxjs/49-hold-to-save-button/tailwind.config.js diff --git a/apps/rxjs/49-hold-to-save-button/tsconfig.app.json b/apps/rxjs/49-hold-to-save-button/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/rxjs/49-hold-to-save-button/tsconfig.editor.json b/apps/rxjs/49-hold-to-save-button/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/rxjs/49-hold-to-save-button/tsconfig.json b/apps/rxjs/49-hold-to-save-button/tsconfig.json new file mode 100644 index 000000000..ad0529440 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/rxjs/49-hold-to-save-button/tsconfig.spec.json b/apps/rxjs/49-hold-to-save-button/tsconfig.spec.json new file mode 100644 index 000000000..a302b0b88 --- /dev/null +++ b/apps/rxjs/49-hold-to-save-button/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/rxjs/catch-error/jest.config.ts b/apps/rxjs/catch-error/jest.config.ts deleted file mode 100644 index f82342048..000000000 --- a/apps/rxjs/catch-error/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'rxjs-catch-error', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/rxjs/catch-error', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/rxjs/catch-error/project.json b/apps/rxjs/catch-error/project.json deleted file mode 100644 index 6776c69fb..000000000 --- a/apps/rxjs/catch-error/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "rxjs-catch-error", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/rxjs/catch-error/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/rxjs/catch-error", - "index": "apps/rxjs/catch-error/src/index.html", - "main": "apps/rxjs/catch-error/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/rxjs/catch-error/tsconfig.app.json", - "assets": [ - "apps/rxjs/catch-error/src/favicon.ico", - "apps/rxjs/catch-error/src/assets" - ], - "styles": ["apps/rxjs/catch-error/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "rxjs-catch-error:build:production" - }, - "development": { - "buildTarget": "rxjs-catch-error:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "rxjs-catch-error:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/rxjs/catch-error/jest.config.ts" - } - } - } -} diff --git a/apps/rxjs/catch-error/src/app/app.component.ts b/apps/rxjs/catch-error/src/app/app.component.ts deleted file mode 100644 index b6ac06679..000000000 --- a/apps/rxjs/catch-error/src/app/app.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { HttpClient } from '@angular/common/http'; -import { Component, DestroyRef, OnInit, inject } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { FormsModule } from '@angular/forms'; -import { Subject, concatMap, map } from 'rxjs'; - -@Component({ - standalone: true, - imports: [CommonModule, FormsModule], - selector: 'app-root', - template: ` -
- - possible values: posts, comments, albums, photos, todos, users - -
-
- - -
-
- {{ response | json }} -
- `, - styleUrls: ['./app.component.css'], -}) -export class AppComponent implements OnInit { - submit$ = new Subject(); - input = ''; - response: unknown; - - private destroyRef = inject(DestroyRef); - private http = inject(HttpClient); - - ngOnInit() { - this.submit$ - .pipe( - map(() => this.input), - concatMap((value) => - this.http.get(`https://jsonplaceholder.typicode.com/${value}/1`), - ), - takeUntilDestroyed(this.destroyRef), - ) - .subscribe({ - next: (value) => { - console.log(value); - this.response = value; - }, - error: (error) => { - console.log(error); - this.response = error; - }, - complete: () => console.log('done'), - }); - } -} diff --git a/apps/rxjs/catch-error/src/app/app.config.ts b/apps/rxjs/catch-error/src/app/app.config.ts deleted file mode 100644 index c5abc2a63..000000000 --- a/apps/rxjs/catch-error/src/app/app.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { HttpClientModule } from '@angular/common/http'; -import { ApplicationConfig, importProvidersFrom } from '@angular/core'; - -export const appConfig: ApplicationConfig = { - providers: [importProvidersFrom(HttpClientModule)], -}; diff --git a/apps/rxjs/catch-error/src/main.ts b/apps/rxjs/catch-error/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/rxjs/catch-error/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/rxjs/catch-error/src/test-setup.ts b/apps/rxjs/catch-error/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/rxjs/catch-error/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/rxjs/catch-error/tsconfig.app.json b/apps/rxjs/catch-error/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/rxjs/catch-error/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/rxjs/catch-error/tsconfig.json b/apps/rxjs/catch-error/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/rxjs/catch-error/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/rxjs/catch-error/tsconfig.spec.json b/apps/rxjs/catch-error/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/rxjs/catch-error/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/rxjs/pipe-bug/README.md b/apps/rxjs/pipe-bug/README.md deleted file mode 100644 index cad896a79..000000000 --- a/apps/rxjs/pipe-bug/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# High Order Operator Bug - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve rxjs-pipe-bug -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/rxjs/11-bug-chaining-operator/). diff --git a/apps/rxjs/pipe-bug/project.json b/apps/rxjs/pipe-bug/project.json deleted file mode 100644 index 44f1f2999..000000000 --- a/apps/rxjs/pipe-bug/project.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "name": "rxjs-pipe-bug", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/rxjs/pipe-bug/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/rxjs/pipe-bug", - "index": "apps/rxjs/pipe-bug/src/index.html", - "main": "apps/rxjs/pipe-bug/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/rxjs/pipe-bug/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/rxjs/pipe-bug/src/favicon.ico", - "apps/rxjs/pipe-bug/src/assets" - ], - "styles": ["apps/rxjs/pipe-bug/src/styles.scss"], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "rxjs-pipe-bug:build:production" - }, - "development": { - "buildTarget": "rxjs-pipe-bug:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "rxjs-pipe-bug:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/rxjs/pipe-bug/src/app/app.component.ts b/apps/rxjs/pipe-bug/src/app/app.component.ts deleted file mode 100644 index f22b16749..000000000 --- a/apps/rxjs/pipe-bug/src/app/app.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable @angular-eslint/component-selector */ -import { AsyncPipe, NgFor } from '@angular/common'; -import { Component, Input, inject } from '@angular/core'; -import { BehaviorSubject, take } from 'rxjs'; -import { AppService } from './app.service'; -import { TopicType } from './localDB.service'; - -@Component({ - standalone: true, - selector: 'button-delete-topic', - imports: [AsyncPipe], - template: ` - -
{{ message$$ | async }}
- `, -}) -export class ButtonDeleteComponent { - @Input() topic!: TopicType; - - message$$ = new BehaviorSubject(''); - - private service = inject(AppService); - - deleteTopic() { - this.service - .deleteOldTopics(this.topic) - .pipe(take(1)) - .subscribe((result) => - this.message$$.next( - result - ? `All ${this.topic} have been deleted` - : `Error: deletion of some ${this.topic} failed`, - ), - ); - } -} - -@Component({ - standalone: true, - imports: [AsyncPipe, NgFor, ButtonDeleteComponent], - selector: 'app-root', - template: ` -
- {{ item.id }} - {{ item.topic }} -
- - Delete Food - Delete Sport - Delete Book - `, -}) -export class AppComponent { - private service = inject(AppService); - - all$ = this.service.getAll$; -} diff --git a/apps/rxjs/pipe-bug/src/app/app.service.ts b/apps/rxjs/pipe-bug/src/app/app.service.ts deleted file mode 100644 index 7c8173514..000000000 --- a/apps/rxjs/pipe-bug/src/app/app.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { inject, Injectable } from '@angular/core'; -import { merge, mergeMap, Observable, of, take } from 'rxjs'; -import { LocalDBService, TopicType } from './localDB.service'; - -@Injectable({ providedIn: 'root' }) -export class AppService { - private dbService = inject(LocalDBService); - - getAll$ = this.dbService.infos$; - - deleteOldTopics(type: TopicType): Observable { - return this.dbService.searchByType(type).pipe( - take(1), - mergeMap((topicToDelete) => - topicToDelete.length > 0 - ? topicToDelete - .map((t) => this.dbService.deleteOneTopic(t.id)) - .reduce((acc, curr) => merge(acc, curr), of(true)) - : of(true), - ), - ); - } -} diff --git a/apps/rxjs/pipe-bug/src/app/localDB.service.ts b/apps/rxjs/pipe-bug/src/app/localDB.service.ts deleted file mode 100644 index d13d0ed9c..000000000 --- a/apps/rxjs/pipe-bug/src/app/localDB.service.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable @typescript-eslint/member-ordering */ -import { randomError } from '@angular-challenges/shared/utils'; -import { Injectable } from '@angular/core'; -import { ComponentStore } from '@ngrx/component-store'; -import { of } from 'rxjs'; - -export type TopicType = 'food' | 'book' | 'sport'; - -interface Info { - id: number; - topic: TopicType; -} - -interface DBState { - infos: Info[]; -} - -const initialState: DBState = { - infos: [ - { id: 1, topic: 'book' }, - { id: 2, topic: 'book' }, - { id: 3, topic: 'book' }, - { id: 4, topic: 'book' }, - { id: 5, topic: 'food' }, - { id: 6, topic: 'food' }, - { id: 7, topic: 'book' }, - { id: 8, topic: 'book' }, - { id: 9, topic: 'book' }, - { id: 10, topic: 'sport' }, - ], -}; - -@Injectable({ providedIn: 'root' }) -export class LocalDBService extends ComponentStore { - constructor() { - super(initialState); - } - - infos$ = this.select((state) => state.infos); - - searchByType = (type: TopicType) => - this.select((state) => state.infos.filter((i) => i.topic === type)); - - deleteOne = this.updater( - (state, id: number): DBState => ({ - infos: state.infos.filter((i) => i.id !== id), - }), - ); - - deleteOneTopic = (id: number) => - randomError({ - success: () => { - this.deleteOne(id); - return of(true); - }, - error: () => of(false), - }); -} diff --git a/apps/rxjs/pipe-bug/src/index.html b/apps/rxjs/pipe-bug/src/index.html deleted file mode 100644 index 401ddc0d8..000000000 --- a/apps/rxjs/pipe-bug/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - RxjsPipeBug - - - - - - - - diff --git a/apps/rxjs/pipe-bug/src/main.ts b/apps/rxjs/pipe-bug/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/rxjs/pipe-bug/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/rxjs/pipe-bug/tsconfig.app.json b/apps/rxjs/pipe-bug/tsconfig.app.json deleted file mode 100644 index 741a69b9f..000000000 --- a/apps/rxjs/pipe-bug/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts"] -} diff --git a/apps/rxjs/pipe-bug/tsconfig.editor.json b/apps/rxjs/pipe-bug/tsconfig.editor.json deleted file mode 100644 index 0f9036b03..000000000 --- a/apps/rxjs/pipe-bug/tsconfig.editor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["**/*.ts"], - "compilerOptions": { - "types": [] - } -} diff --git a/apps/rxjs/pipe-bug/tsconfig.json b/apps/rxjs/pipe-bug/tsconfig.json deleted file mode 100644 index 6091bd910..000000000 --- a/apps/rxjs/pipe-bug/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/rxjs/race-condition/cypress.config.ts b/apps/rxjs/race-condition/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/rxjs/race-condition/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/rxjs/race-condition/jest.config.ts b/apps/rxjs/race-condition/jest.config.ts deleted file mode 100644 index 2e2e8920b..000000000 --- a/apps/rxjs/race-condition/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'rxjs-race-condition', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/apps/rxjs/race-condition', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/rxjs/race-condition/project.json b/apps/rxjs/race-condition/project.json deleted file mode 100644 index 2f91c369f..000000000 --- a/apps/rxjs/race-condition/project.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "rxjs-race-condition", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/rxjs/race-condition/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/rxjs/race-condition", - "index": "apps/rxjs/race-condition/src/index.html", - "main": "apps/rxjs/race-condition/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/rxjs/race-condition/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/rxjs/race-condition/src/favicon.ico", - "apps/rxjs/race-condition/src/assets" - ], - "styles": ["apps/rxjs/race-condition/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "rxjs-race-condition:build:production" - }, - "development": { - "buildTarget": "rxjs-race-condition:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "rxjs-race-condition:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/rxjs/race-condition/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/rxjs/race-condition/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "rxjs-race-condition:build" - } - } - }, - "tags": [] -} diff --git a/apps/rxjs/race-condition/src/app/app.component.ts b/apps/rxjs/race-condition/src/app/app.component.ts deleted file mode 100644 index a7eb77710..000000000 --- a/apps/rxjs/race-condition/src/app/app.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - inject, - OnInit, -} from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { take } from 'rxjs'; -import { TopicModalComponent } from './topic-dialog.component'; -import { TopicService, TopicType } from './topic.service'; - -@Component({ - standalone: true, - selector: 'app-root', - template: ` - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AppComponent implements OnInit { - title = 'rxjs-race-condition'; - dialog = inject(MatDialog); - topicService = inject(TopicService); - topics: TopicType[] = []; - - ngOnInit(): void { - this.topicService - .fakeGetHttpTopic() - .pipe(take(1)) - .subscribe((topics) => (this.topics = topics)); - } - - openTopicModal() { - this.dialog.open(TopicModalComponent, { - data: { - topics: this.topics, - }, - }); - } -} diff --git a/apps/rxjs/race-condition/src/app/topic-dialog.component.ts b/apps/rxjs/race-condition/src/app/topic-dialog.component.ts deleted file mode 100644 index d63ed4ada..000000000 --- a/apps/rxjs/race-condition/src/app/topic-dialog.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { NgFor } from '@angular/common'; -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; - -@Component({ - template: ` -

Show all Topics

-
-
    -
  • - {{ topic }} -
  • -
-
-
- -
- `, - imports: [MatDialogModule, MatButtonModule, NgFor], - standalone: true, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TopicModalComponent { - data = inject(MAT_DIALOG_DATA); -} diff --git a/apps/rxjs/race-condition/src/index.html b/apps/rxjs/race-condition/src/index.html deleted file mode 100644 index af7595012..000000000 --- a/apps/rxjs/race-condition/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - RxjsRaceCondition - - - - - - - - diff --git a/apps/rxjs/race-condition/src/main.ts b/apps/rxjs/race-condition/src/main.ts deleted file mode 100644 index 9bb5c3023..000000000 --- a/apps/rxjs/race-condition/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { appConfig } from './app/app.config'; - -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/rxjs/race-condition/src/styles.scss b/apps/rxjs/race-condition/src/styles.scss deleted file mode 100644 index 5f2e97eb4..000000000 --- a/apps/rxjs/race-condition/src/styles.scss +++ /dev/null @@ -1,24 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ - -@use '@angular/material' as mat; - -@include mat.core(); - -$theme-primary: mat.define-palette(mat.$indigo-palette); -$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - -$theme-warn: mat.define-palette(mat.$red-palette); - -$theme: mat.define-light-theme( - ( - color: ( - primary: $theme-primary, - accent: $theme-accent, - warn: $theme-warn, - ), - typography: mat.define-typography-config(), - ) -); - -@include mat.dialog-theme($theme); -@include mat.button-theme($theme); diff --git a/apps/rxjs/race-condition/src/test-setup.ts b/apps/rxjs/race-condition/src/test-setup.ts deleted file mode 100644 index 1100b3e8a..000000000 --- a/apps/rxjs/race-condition/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular/setup-jest'; diff --git a/apps/rxjs/race-condition/tsconfig.app.json b/apps/rxjs/race-condition/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/rxjs/race-condition/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/rxjs/race-condition/tsconfig.json b/apps/rxjs/race-condition/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/rxjs/race-condition/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/rxjs/race-condition/tsconfig.spec.json b/apps/rxjs/race-condition/tsconfig.spec.json deleted file mode 100644 index ca14cc622..000000000 --- a/apps/rxjs/race-condition/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/rxjs/race-condition/.eslintrc.json b/apps/signal/30-interop-rxjs-signal/.eslintrc.json similarity index 100% rename from apps/rxjs/race-condition/.eslintrc.json rename to apps/signal/30-interop-rxjs-signal/.eslintrc.json diff --git a/apps/signal/30-interop-rxjs-signal/README.md b/apps/signal/30-interop-rxjs-signal/README.md new file mode 100644 index 000000000..f726d1b0f --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/README.md @@ -0,0 +1,13 @@ +# Interoperability Rxjs/Signal + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-interop-rxjs-signal +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/30-interop-rxjs-signal/). diff --git a/apps/signal/30-interop-rxjs-signal/jest.config.ts b/apps/signal/30-interop-rxjs-signal/jest.config.ts new file mode 100644 index 000000000..6d0cac0cd --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'signal-interop-rxjs-signal', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/signal/30-interop-rxjs-signal', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/signal/30-interop-rxjs-signal/project.json b/apps/signal/30-interop-rxjs-signal/project.json new file mode 100644 index 000000000..b03dd4c15 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/project.json @@ -0,0 +1,86 @@ +{ + "name": "signal-interop-rxjs-signal", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/30-interop-rxjs-signal/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/30-interop-rxjs-signal", + "index": "apps/signal/30-interop-rxjs-signal/src/index.html", + "main": "apps/signal/30-interop-rxjs-signal/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/30-interop-rxjs-signal/tsconfig.app.json", + "assets": [ + "apps/signal/30-interop-rxjs-signal/src/favicon.ico", + "apps/signal/30-interop-rxjs-signal/src/assets" + ], + "styles": [ + "apps/signal/30-interop-rxjs-signal/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-interop-rxjs-signal:build:production" + }, + "development": { + "buildTarget": "signal-interop-rxjs-signal:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-interop-rxjs-signal:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/signal/30-interop-rxjs-signal/src/app/app.component.ts b/apps/signal/30-interop-rxjs-signal/src/app/app.component.ts new file mode 100644 index 000000000..54fa2b85d --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/app/app.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` + + `, + styles: [''], +}) +export class AppComponent {} diff --git a/apps/angular/interop-rxjs-signal/src/app/app.config.ts b/apps/signal/30-interop-rxjs-signal/src/app/app.config.ts similarity index 100% rename from apps/angular/interop-rxjs-signal/src/app/app.config.ts rename to apps/signal/30-interop-rxjs-signal/src/app/app.config.ts diff --git a/apps/signal/30-interop-rxjs-signal/src/app/detail/detail.component.ts b/apps/signal/30-interop-rxjs-signal/src/app/detail/detail.component.ts new file mode 100644 index 000000000..070bf7d7c --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/app/detail/detail.component.ts @@ -0,0 +1,44 @@ +import { DatePipe } from '@angular/common'; +import { Component, Input as RouterInput } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { Photo } from '../photo.model'; + +@Component({ + selector: 'app-photos', + imports: [DatePipe, RouterLink], + template: ` + {{ photo.title }} +

+ Title: + {{ photo.title }} +

+

+ Owner: + {{ photo.ownername }} +

+

+ Date: + {{ photo.datetaken | date }} +

+

+ Tags: + {{ photo.tags }} +

+ + + `, + host: { + class: 'p-5 block', + }, +}) +export default class DetailComponent { + @RouterInput({ + required: true, + transform: (value: string) => JSON.parse(decodeURIComponent(value)), + }) + photo!: Photo; +} diff --git a/apps/signal/30-interop-rxjs-signal/src/app/list/photos.component.ts b/apps/signal/30-interop-rxjs-signal/src/app/list/photos.component.ts new file mode 100644 index 000000000..7ba115027 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/app/list/photos.component.ts @@ -0,0 +1,128 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { RouterLinkWithHref } from '@angular/router'; +import { provideComponentStore } from '@ngrx/component-store'; +import { + debounceTime, + distinctUntilChanged, + Observable, + skipWhile, + tap, +} from 'rxjs'; +import { Photo } from '../photo.model'; +import { PhotoStore } from './photos.store'; + +@Component({ + selector: 'app-photos', + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatProgressBarModule, + MatInputModule, + RouterLinkWithHref, + AsyncPipe, + ], + template: ` +

Photos

+ + + Search + + + + @let vm = vm$ | async; +
+
+ + + Page :{{ vm.page }} / {{ vm.pages }} +
+ @if (vm.loading) { + + } + @if (vm.photos && vm.photos.length > 0) { +
    + @for ( + photo of vm.photos; + track photo.id; + let i = $index + ) { +
  • + + {{ photo.title }} + +
  • + } +
+ } @else { +
No Photos found. Type a search word.
+ } +
+ {{ vm.error }} +
+
+ `, + providers: [provideComponentStore(PhotoStore)], + host: { + class: 'p-5 block', + }, +}) +export default class PhotosComponent implements OnInit { + store = inject(PhotoStore); + readonly vm$: Observable<{ + photos: Photo[]; + search: string; + page: number; + pages: number; + endOfPage: boolean; + loading: boolean; + error: unknown; + }> = this.store.vm$.pipe( + tap(({ search }) => { + if (!this.formInit) { + this.search.setValue(search); + this.formInit = true; + } + }), + ); + + private formInit = false; + search = new FormControl(); + + ngOnInit(): void { + this.store.search( + this.search.valueChanges.pipe( + skipWhile(() => !this.formInit), + debounceTime(300), + distinctUntilChanged(), + ), + ); + } + + encode(photo: Photo) { + return encodeURIComponent(JSON.stringify(photo)); + } +} diff --git a/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts b/apps/signal/30-interop-rxjs-signal/src/app/list/photos.store.ts similarity index 96% rename from apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts rename to apps/signal/30-interop-rxjs-signal/src/app/list/photos.store.ts index 01de2d4ec..f1315e87e 100644 --- a/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts +++ b/apps/signal/30-interop-rxjs-signal/src/app/list/photos.store.ts @@ -1,10 +1,10 @@ -import { Injectable, inject } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ComponentStore, OnStateInit, OnStoreInit, - tapResponse, } from '@ngrx/component-store'; +import { tapResponse } from '@ngrx/operators'; import { pipe } from 'rxjs'; import { filter, mergeMap, tap } from 'rxjs/operators'; import { Photo } from '../photo.model'; diff --git a/apps/angular/interop-rxjs-signal/src/app/photo.model.ts b/apps/signal/30-interop-rxjs-signal/src/app/photo.model.ts similarity index 100% rename from apps/angular/interop-rxjs-signal/src/app/photo.model.ts rename to apps/signal/30-interop-rxjs-signal/src/app/photo.model.ts diff --git a/apps/angular/interop-rxjs-signal/src/app/photos.service.ts b/apps/signal/30-interop-rxjs-signal/src/app/photos.service.ts similarity index 100% rename from apps/angular/interop-rxjs-signal/src/app/photos.service.ts rename to apps/signal/30-interop-rxjs-signal/src/app/photos.service.ts diff --git a/apps/rxjs/pipe-bug/src/assets/.gitkeep b/apps/signal/30-interop-rxjs-signal/src/assets/.gitkeep similarity index 100% rename from apps/rxjs/pipe-bug/src/assets/.gitkeep rename to apps/signal/30-interop-rxjs-signal/src/assets/.gitkeep diff --git a/apps/testing/input-output/src/favicon.ico b/apps/signal/30-interop-rxjs-signal/src/favicon.ico similarity index 100% rename from apps/testing/input-output/src/favicon.ico rename to apps/signal/30-interop-rxjs-signal/src/favicon.ico diff --git a/apps/signal/30-interop-rxjs-signal/src/index.html b/apps/signal/30-interop-rxjs-signal/src/index.html new file mode 100644 index 000000000..c8a8e0de5 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-interop-rxjs-signal + + + + + + + + diff --git a/apps/signal/30-interop-rxjs-signal/src/main.ts b/apps/signal/30-interop-rxjs-signal/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/signal/30-interop-rxjs-signal/src/styles.scss b/apps/signal/30-interop-rxjs-signal/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/30-interop-rxjs-signal/src/test-setup.ts b/apps/signal/30-interop-rxjs-signal/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/typescript/enums-vs-union-types/tailwind.config.js b/apps/signal/30-interop-rxjs-signal/tailwind.config.js similarity index 100% rename from apps/typescript/enums-vs-union-types/tailwind.config.js rename to apps/signal/30-interop-rxjs-signal/tailwind.config.js diff --git a/apps/signal/30-interop-rxjs-signal/tsconfig.app.json b/apps/signal/30-interop-rxjs-signal/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/rxjs/race-condition/tsconfig.editor.json b/apps/signal/30-interop-rxjs-signal/tsconfig.editor.json similarity index 100% rename from apps/rxjs/race-condition/tsconfig.editor.json rename to apps/signal/30-interop-rxjs-signal/tsconfig.editor.json diff --git a/apps/signal/30-interop-rxjs-signal/tsconfig.json b/apps/signal/30-interop-rxjs-signal/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/30-interop-rxjs-signal/tsconfig.spec.json b/apps/signal/30-interop-rxjs-signal/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/signal/30-interop-rxjs-signal/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/signal/43-signal-input/.eslintrc.json b/apps/signal/43-signal-input/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/signal/43-signal-input/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/43-signal-input/README.md b/apps/signal/43-signal-input/README.md new file mode 100644 index 000000000..d82216bfd --- /dev/null +++ b/apps/signal/43-signal-input/README.md @@ -0,0 +1,13 @@ +# Signal Input + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-signal-input +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/signal/43-signal-input). diff --git a/apps/signal/43-signal-input/project.json b/apps/signal/43-signal-input/project.json new file mode 100644 index 000000000..0a1832ffb --- /dev/null +++ b/apps/signal/43-signal-input/project.json @@ -0,0 +1,70 @@ +{ + "name": "signal-signal-input", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/43-signal-input/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/43-signal-input", + "index": "apps/signal/43-signal-input/src/index.html", + "browser": "apps/signal/43-signal-input/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/43-signal-input/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/signal/43-signal-input/src/favicon.ico", + "apps/signal/43-signal-input/src/assets" + ], + "styles": ["apps/signal/43-signal-input/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-signal-input:build:production" + }, + "development": { + "buildTarget": "signal-signal-input:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-signal-input:build" + } + } + } +} diff --git a/apps/signal/43-signal-input/src/app/app.component.ts b/apps/signal/43-signal-input/src/app/app.component.ts new file mode 100644 index 000000000..5c2deb684 --- /dev/null +++ b/apps/signal/43-signal-input/src/app/app.component.ts @@ -0,0 +1,43 @@ +import { Component } from '@angular/core'; +import { UserComponent } from './user.component'; + +@Component({ + imports: [UserComponent], + selector: 'app-root', + template: ` +
+
+ Name: + + @if (showUser && !name.value) { +
name required
+ } +
+
+ LastName: + +
+
+ Age: + +
+ +
+ @if (showUser && !!name.value) { + + } + `, + host: { + class: 'p-10 block flex flex-col gap-10', + }, +}) +export class AppComponent { + showUser = false; +} diff --git a/apps/typescript/enums-vs-union-types/src/app/app.config.ts b/apps/signal/43-signal-input/src/app/app.config.ts similarity index 100% rename from apps/typescript/enums-vs-union-types/src/app/app.config.ts rename to apps/signal/43-signal-input/src/app/app.config.ts diff --git a/apps/angular/signal-input/src/app/user.component.ts b/apps/signal/43-signal-input/src/app/user.component.ts similarity index 98% rename from apps/angular/signal-input/src/app/user.component.ts rename to apps/signal/43-signal-input/src/app/user.component.ts index 082638bf6..908f952c3 100644 --- a/apps/angular/signal-input/src/app/user.component.ts +++ b/apps/signal/43-signal-input/src/app/user.component.ts @@ -16,7 +16,6 @@ const ageToCategory = (age: number): Category => { @Component({ selector: 'app-user', - standalone: true, imports: [TitleCasePipe], template: ` {{ fullName | titlecase }} plays tennis in the {{ category }} category!! diff --git a/apps/rxjs/race-condition/src/assets/.gitkeep b/apps/signal/43-signal-input/src/assets/.gitkeep similarity index 100% rename from apps/rxjs/race-condition/src/assets/.gitkeep rename to apps/signal/43-signal-input/src/assets/.gitkeep diff --git a/apps/testing/modal/src/favicon.ico b/apps/signal/43-signal-input/src/favicon.ico similarity index 100% rename from apps/testing/modal/src/favicon.ico rename to apps/signal/43-signal-input/src/favicon.ico diff --git a/apps/signal/43-signal-input/src/index.html b/apps/signal/43-signal-input/src/index.html new file mode 100644 index 000000000..642a346a4 --- /dev/null +++ b/apps/signal/43-signal-input/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-signal-input + + + + + + + + diff --git a/apps/signal/43-signal-input/src/main.ts b/apps/signal/43-signal-input/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/signal/43-signal-input/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/signal/43-signal-input/src/styles.scss b/apps/signal/43-signal-input/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/43-signal-input/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/43-signal-input/tailwind.config.js b/apps/signal/43-signal-input/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/43-signal-input/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/43-signal-input/tsconfig.app.json b/apps/signal/43-signal-input/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/43-signal-input/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/performance/ngfor-biglist/tsconfig.editor.json b/apps/signal/43-signal-input/tsconfig.editor.json similarity index 100% rename from apps/performance/ngfor-biglist/tsconfig.editor.json rename to apps/signal/43-signal-input/tsconfig.editor.json diff --git a/apps/signal/43-signal-input/tsconfig.json b/apps/signal/43-signal-input/tsconfig.json new file mode 100644 index 000000000..7cfcc3b0b --- /dev/null +++ b/apps/signal/43-signal-input/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/50-bug-in-effect/.eslintrc.json b/apps/signal/50-bug-in-effect/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/signal/50-bug-in-effect/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/50-bug-in-effect/README.md b/apps/signal/50-bug-in-effect/README.md new file mode 100644 index 000000000..9e55d151a --- /dev/null +++ b/apps/signal/50-bug-in-effect/README.md @@ -0,0 +1,13 @@ +# Bug in Effect ? + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-bug-in-effect +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/50-bug-effect-signal/). diff --git a/apps/signal/50-bug-in-effect/project.json b/apps/signal/50-bug-in-effect/project.json new file mode 100644 index 000000000..7d40e2caa --- /dev/null +++ b/apps/signal/50-bug-in-effect/project.json @@ -0,0 +1,70 @@ +{ + "name": "signal-bug-in-effect", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/50-bug-in-effect/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/50-bug-in-effect", + "index": "apps/signal/50-bug-in-effect/src/index.html", + "browser": "apps/signal/50-bug-in-effect/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/50-bug-in-effect/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/signal/50-bug-in-effect/src/favicon.ico", + "apps/signal/50-bug-in-effect/src/assets" + ], + "styles": ["apps/signal/50-bug-in-effect/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-bug-in-effect:build:production" + }, + "development": { + "buildTarget": "signal-bug-in-effect:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-bug-in-effect:build" + } + } + } +} diff --git a/apps/signal/50-bug-in-effect/src/app/app.component.ts b/apps/signal/50-bug-in-effect/src/app/app.component.ts new file mode 100644 index 000000000..ec6ba09b0 --- /dev/null +++ b/apps/signal/50-bug-in-effect/src/app/app.component.ts @@ -0,0 +1,52 @@ +import { + ChangeDetectionStrategy, + Component, + effect, + model, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +@Component({ + imports: [FormsModule], + selector: 'app-root', + template: ` +
+

MacBook

+

1999,99 €

+
+ +
+

Extras:

+ +
+ + +500 GB drive-space +
+
+ + +4 GB RAM +
+
+ + Better GPU +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + drive = model(false); + ram = model(false); + gpu = model(false); + + constructor() { + /* + Explain for your junior team mate why this bug occurs ... + */ + effect(() => { + if (this.drive() || this.ram() || this.gpu()) { + alert('Price increased!'); + } + }); + } +} diff --git a/apps/signal/50-bug-in-effect/src/app/app.config.ts b/apps/signal/50-bug-in-effect/src/app/app.config.ts new file mode 100644 index 000000000..81a6edde4 --- /dev/null +++ b/apps/signal/50-bug-in-effect/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/testing/checkbox/src/assets/.gitkeep b/apps/signal/50-bug-in-effect/src/assets/.gitkeep similarity index 100% rename from apps/testing/checkbox/src/assets/.gitkeep rename to apps/signal/50-bug-in-effect/src/assets/.gitkeep diff --git a/apps/testing/nested/src/favicon.ico b/apps/signal/50-bug-in-effect/src/favicon.ico similarity index 100% rename from apps/testing/nested/src/favicon.ico rename to apps/signal/50-bug-in-effect/src/favicon.ico diff --git a/apps/signal/50-bug-in-effect/src/index.html b/apps/signal/50-bug-in-effect/src/index.html new file mode 100644 index 000000000..e8f5b7364 --- /dev/null +++ b/apps/signal/50-bug-in-effect/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-bug-in-effect + + + + + + + + diff --git a/apps/signal/50-bug-in-effect/src/main.ts b/apps/signal/50-bug-in-effect/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/signal/50-bug-in-effect/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/signal/50-bug-in-effect/src/styles.scss b/apps/signal/50-bug-in-effect/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/50-bug-in-effect/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/50-bug-in-effect/tailwind.config.js b/apps/signal/50-bug-in-effect/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/50-bug-in-effect/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/50-bug-in-effect/tsconfig.app.json b/apps/signal/50-bug-in-effect/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/50-bug-in-effect/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/50-bug-in-effect/tsconfig.editor.json b/apps/signal/50-bug-in-effect/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/signal/50-bug-in-effect/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/50-bug-in-effect/tsconfig.json b/apps/signal/50-bug-in-effect/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/signal/50-bug-in-effect/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/51-function-call-effect/.eslintrc.json b/apps/signal/51-function-call-effect/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/signal/51-function-call-effect/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/51-function-call-effect/README.md b/apps/signal/51-function-call-effect/README.md new file mode 100644 index 000000000..6d4543361 --- /dev/null +++ b/apps/signal/51-function-call-effect/README.md @@ -0,0 +1,13 @@ +# Function call in effect + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-function-call-effect +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/51-function-call-effect/). diff --git a/apps/signal/51-function-call-effect/project.json b/apps/signal/51-function-call-effect/project.json new file mode 100644 index 000000000..71e6f233d --- /dev/null +++ b/apps/signal/51-function-call-effect/project.json @@ -0,0 +1,70 @@ +{ + "name": "signal-function-call-effect", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/51-function-call-effect/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/51-function-call-effect", + "index": "apps/signal/51-function-call-effect/src/index.html", + "browser": "apps/signal/51-function-call-effect/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/51-function-call-effect/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/signal/51-function-call-effect/src/favicon.ico", + "apps/signal/51-function-call-effect/src/assets" + ], + "styles": ["apps/signal/51-function-call-effect/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-function-call-effect:build:production" + }, + "development": { + "buildTarget": "signal-function-call-effect:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-function-call-effect:build" + } + } + } +} diff --git a/apps/signal/51-function-call-effect/src/app/action.component.ts b/apps/signal/51-function-call-effect/src/app/action.component.ts new file mode 100644 index 000000000..22e0e7a4f --- /dev/null +++ b/apps/signal/51-function-call-effect/src/app/action.component.ts @@ -0,0 +1,44 @@ +import { + ChangeDetectionStrategy, + Component, + effect, + inject, + signal, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { UserService } from './user.service'; + +@Component({ + imports: [FormsModule], + selector: 'app-actions', + template: ` +
+ + +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ActionsComponent { + private userService = inject(UserService); + protected action = signal(undefined); + + protected actions = ['Create', 'Read', 'Update', 'Delete']; + + constructor() { + effect(() => { + this.userService.log(this.action() ?? 'No action selected'); + }); + } +} diff --git a/apps/signal/51-function-call-effect/src/app/app.component.ts b/apps/signal/51-function-call-effect/src/app/app.component.ts new file mode 100644 index 000000000..5f9342eda --- /dev/null +++ b/apps/signal/51-function-call-effect/src/app/app.component.ts @@ -0,0 +1,33 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ActionsComponent } from './action.component'; +import { UserService } from './user.service'; + +@Component({ + imports: [FormsModule, ActionsComponent], + selector: 'app-root', + template: ` + + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + protected userService = inject(UserService); + + protected users = ['Thomas', 'John', 'Alice', 'Bob', 'Charlie', 'David']; +} diff --git a/apps/signal/51-function-call-effect/src/app/app.config.ts b/apps/signal/51-function-call-effect/src/app/app.config.ts new file mode 100644 index 000000000..81a6edde4 --- /dev/null +++ b/apps/signal/51-function-call-effect/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/signal/51-function-call-effect/src/app/user.service.ts b/apps/signal/51-function-call-effect/src/app/user.service.ts new file mode 100644 index 000000000..b43756b9e --- /dev/null +++ b/apps/signal/51-function-call-effect/src/app/user.service.ts @@ -0,0 +1,10 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class UserService { + name = signal('Thomas'); + + log(message: string) { + console.log(`${this.name()}: ${message}`); + } +} diff --git a/apps/testing/create-harness/src/assets/.gitkeep b/apps/signal/51-function-call-effect/src/assets/.gitkeep similarity index 100% rename from apps/testing/create-harness/src/assets/.gitkeep rename to apps/signal/51-function-call-effect/src/assets/.gitkeep diff --git a/apps/testing/router-outlet/src/favicon.ico b/apps/signal/51-function-call-effect/src/favicon.ico similarity index 100% rename from apps/testing/router-outlet/src/favicon.ico rename to apps/signal/51-function-call-effect/src/favicon.ico diff --git a/apps/signal/51-function-call-effect/src/index.html b/apps/signal/51-function-call-effect/src/index.html new file mode 100644 index 000000000..523bcaef2 --- /dev/null +++ b/apps/signal/51-function-call-effect/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-function-call-effect + + + + + + + + diff --git a/apps/signal/51-function-call-effect/src/main.ts b/apps/signal/51-function-call-effect/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/signal/51-function-call-effect/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/signal/51-function-call-effect/src/styles.scss b/apps/signal/51-function-call-effect/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/51-function-call-effect/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/51-function-call-effect/tailwind.config.js b/apps/signal/51-function-call-effect/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/51-function-call-effect/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/51-function-call-effect/tsconfig.app.json b/apps/signal/51-function-call-effect/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/51-function-call-effect/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/51-function-call-effect/tsconfig.editor.json b/apps/signal/51-function-call-effect/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/signal/51-function-call-effect/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/51-function-call-effect/tsconfig.json b/apps/signal/51-function-call-effect/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/signal/51-function-call-effect/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/53-big-signal-performance/.eslintrc.json b/apps/signal/53-big-signal-performance/.eslintrc.json new file mode 100644 index 000000000..d3cd7997a --- /dev/null +++ b/apps/signal/53-big-signal-performance/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": {} + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/53-big-signal-performance/README.md b/apps/signal/53-big-signal-performance/README.md new file mode 100644 index 000000000..2b1b56672 --- /dev/null +++ b/apps/signal/53-big-signal-performance/README.md @@ -0,0 +1,13 @@ +# Big Signal Performance + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-big-signal-performance +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/signal/52-big-signal-performance/). diff --git a/apps/signal/53-big-signal-performance/project.json b/apps/signal/53-big-signal-performance/project.json new file mode 100644 index 000000000..9795c4032 --- /dev/null +++ b/apps/signal/53-big-signal-performance/project.json @@ -0,0 +1,70 @@ +{ + "name": "signal-big-signal-performance", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/53-big-signal-performance/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/53-big-signal-performance", + "index": "apps/signal/53-big-signal-performance/src/index.html", + "browser": "apps/signal/53-big-signal-performance/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/53-big-signal-performance/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/signal/53-big-signal-performance/src/favicon.ico", + "apps/signal/53-big-signal-performance/src/assets" + ], + "styles": ["apps/signal/53-big-signal-performance/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-big-signal-performance:build:production" + }, + "development": { + "buildTarget": "signal-big-signal-performance:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-big-signal-performance:build" + } + } + } +} diff --git a/apps/signal/53-big-signal-performance/src/app/address.component.ts b/apps/signal/53-big-signal-performance/src/app/address.component.ts new file mode 100644 index 000000000..f894d697e --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/address.component.ts @@ -0,0 +1,20 @@ +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { UserStore } from './user.service'; + +@Component({ + selector: 'address-user', + template: ` +
+ Address: +
Street: {{ userService.user().address.street }}
+
ZipCode: {{ userService.user().address.zipCode }}
+
City: {{ userService.user().address.city }}
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CDFlashingDirective], +}) +export class AddressComponent { + userService = inject(UserStore); +} diff --git a/apps/signal/53-big-signal-performance/src/app/app.component.ts b/apps/signal/53-big-signal-performance/src/app/app.component.ts new file mode 100644 index 000000000..bf15a5dc2 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/app.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; +import { AddressComponent } from './address.component'; +import { JobComponent } from './job.component'; +import { NameComponent } from './name.component'; +import { NoteComponent } from './note.component'; +import { UserFormComponent } from './user-form.component'; + +@Component({ + selector: 'app-root', + template: ` + + + + + + `, + styles: [''], + imports: [ + JobComponent, + NameComponent, + AddressComponent, + NoteComponent, + UserFormComponent, + ], +}) +export class AppComponent {} diff --git a/apps/signal/53-big-signal-performance/src/app/app.config.ts b/apps/signal/53-big-signal-performance/src/app/app.config.ts new file mode 100644 index 000000000..81a6edde4 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/signal/53-big-signal-performance/src/app/job.component.ts b/apps/signal/53-big-signal-performance/src/app/job.component.ts new file mode 100644 index 000000000..d3186fc9f --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/job.component.ts @@ -0,0 +1,19 @@ +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { UserStore } from './user.service'; + +@Component({ + selector: 'job', + template: ` +
+ Job: +
title: {{ userService.user().title }}
+
salary: {{ userService.user().salary }}
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CDFlashingDirective], +}) +export class JobComponent { + userService = inject(UserStore); +} diff --git a/apps/signal/53-big-signal-performance/src/app/name.component.ts b/apps/signal/53-big-signal-performance/src/app/name.component.ts new file mode 100644 index 000000000..f93b5675a --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/name.component.ts @@ -0,0 +1,17 @@ +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { UserStore } from './user.service'; + +@Component({ + selector: 'name', + template: ` +
+ Name: {{ userService.user().name }} +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CDFlashingDirective], +}) +export class NameComponent { + userService = inject(UserStore); +} diff --git a/apps/signal/53-big-signal-performance/src/app/note.component.ts b/apps/signal/53-big-signal-performance/src/app/note.component.ts new file mode 100644 index 000000000..dd0033962 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/note.component.ts @@ -0,0 +1,17 @@ +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { UserStore } from './user.service'; + +@Component({ + selector: 'note', + template: ` +
+ Note: {{ userService.user().note }} +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CDFlashingDirective], +}) +export class NoteComponent { + userService = inject(UserStore); +} diff --git a/apps/signal/53-big-signal-performance/src/app/user-form.component.ts b/apps/signal/53-big-signal-performance/src/app/user-form.component.ts new file mode 100644 index 000000000..d0f2164ce --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/user-form.component.ts @@ -0,0 +1,99 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { UserStore } from './user.service'; + +@Component({ + selector: 'user-form', + imports: [ReactiveFormsModule], + template: ` +
+
+ Name: + +
+
+ Address: +
+ street: + +
+
+ zipCode: + +
+
+ city: + +
+
+
+ note: + +
+
+ title: + +
+
+ salary: + +
+ +
+ `, + host: { + class: 'block border border-gray-500 p-4 pt-10 m-4', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UserFormComponent { + userStore = inject(UserStore); + + form = new FormGroup({ + name: new FormControl(this.userStore.user().name, { nonNullable: true }), + street: new FormControl(this.userStore.user().address.street, { + nonNullable: true, + }), + zipCode: new FormControl(this.userStore.user().address.zipCode, { + nonNullable: true, + }), + city: new FormControl(this.userStore.user().address.city, { + nonNullable: true, + }), + note: new FormControl(this.userStore.user().note, { nonNullable: true }), + title: new FormControl(this.userStore.user().title, { nonNullable: true }), + salary: new FormControl(this.userStore.user().salary, { + nonNullable: true, + }), + }); + + submit() { + this.userStore.user.update((u) => ({ + ...u, + name: this.form.getRawValue().name, + address: { + ...u.address, + street: this.form.getRawValue().street, + zipCode: this.form.getRawValue().zipCode, + city: this.form.getRawValue().city, + }, + note: this.form.getRawValue().note, + title: this.form.getRawValue().title, + salary: this.form.getRawValue().salary, + })); + } +} diff --git a/apps/signal/53-big-signal-performance/src/app/user.service.ts b/apps/signal/53-big-signal-performance/src/app/user.service.ts new file mode 100644 index 000000000..4b3b7c512 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/app/user.service.ts @@ -0,0 +1,16 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class UserStore { + user = signal({ + name: 'Bob', + address: { + street: '', + zipCode: '', + city: '', + }, + note: '', + title: '', + salary: 0, + }); +} diff --git a/apps/testing/harness/src/assets/.gitkeep b/apps/signal/53-big-signal-performance/src/assets/.gitkeep similarity index 100% rename from apps/testing/harness/src/assets/.gitkeep rename to apps/signal/53-big-signal-performance/src/assets/.gitkeep diff --git a/apps/testing/table/src/favicon.ico b/apps/signal/53-big-signal-performance/src/favicon.ico similarity index 100% rename from apps/testing/table/src/favicon.ico rename to apps/signal/53-big-signal-performance/src/favicon.ico diff --git a/apps/signal/53-big-signal-performance/src/index.html b/apps/signal/53-big-signal-performance/src/index.html new file mode 100644 index 000000000..3f038cc7a --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-big-signal-performance + + + + + + + + diff --git a/apps/signal/53-big-signal-performance/src/main.ts b/apps/signal/53-big-signal-performance/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/signal/53-big-signal-performance/src/styles.scss b/apps/signal/53-big-signal-performance/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/53-big-signal-performance/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/53-big-signal-performance/tailwind.config.js b/apps/signal/53-big-signal-performance/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/53-big-signal-performance/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/53-big-signal-performance/tsconfig.app.json b/apps/signal/53-big-signal-performance/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/53-big-signal-performance/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/53-big-signal-performance/tsconfig.editor.json b/apps/signal/53-big-signal-performance/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/signal/53-big-signal-performance/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/53-big-signal-performance/tsconfig.json b/apps/signal/53-big-signal-performance/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/signal/53-big-signal-performance/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/54-pipe-observable-to-signal/.eslintrc.json b/apps/signal/54-pipe-observable-to-signal/.eslintrc.json new file mode 100644 index 000000000..d3cd7997a --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": {} + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/54-pipe-observable-to-signal/README.md b/apps/signal/54-pipe-observable-to-signal/README.md new file mode 100644 index 000000000..495cd3aa9 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/README.md @@ -0,0 +1,13 @@ +# Pipe Observable to Signal + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-pipe-observable-to-signal +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/signal/54-pipe-observable-to-signal/). diff --git a/apps/signal/54-pipe-observable-to-signal/project.json b/apps/signal/54-pipe-observable-to-signal/project.json new file mode 100644 index 000000000..1f95f6036 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/project.json @@ -0,0 +1,70 @@ +{ + "name": "signal-pipe-observable-to-signal", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/54-pipe-observable-to-signal/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/54-pipe-observable-to-signal", + "index": "apps/signal/54-pipe-observable-to-signal/src/index.html", + "browser": "apps/signal/54-pipe-observable-to-signal/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/54-pipe-observable-to-signal/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/signal/54-pipe-observable-to-signal/src/favicon.ico", + "apps/signal/54-pipe-observable-to-signal/src/assets" + ], + "styles": ["apps/signal/54-pipe-observable-to-signal/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-pipe-observable-to-signal:build:production" + }, + "development": { + "buildTarget": "signal-pipe-observable-to-signal:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-pipe-observable-to-signal:build" + } + } + } +} diff --git a/apps/signal/54-pipe-observable-to-signal/src/app/app.component.ts b/apps/signal/54-pipe-observable-to-signal/src/app/app.component.ts new file mode 100644 index 000000000..72fe7106e --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/app/app.component.ts @@ -0,0 +1,28 @@ +import { TableComponent } from '@angular-challenges/shared/ui'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ProductRowComponent } from './product-row.component'; +import { products } from './product.model'; + +@Component({ + imports: [TableComponent, ProductRowComponent], + selector: 'app-root', + template: ` + + + + @for (col of displayedColumns; track col) { + + } + + + + + +
{{ col }}
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + products = products; + displayedColumns = ['name', 'priceA', 'priceB', 'priceC']; +} diff --git a/apps/signal/54-pipe-observable-to-signal/src/app/currency.pipe.ts b/apps/signal/54-pipe-observable-to-signal/src/app/currency.pipe.ts new file mode 100644 index 000000000..411243b81 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/app/currency.pipe.ts @@ -0,0 +1,14 @@ +import { inject, Pipe, PipeTransform } from '@angular/core'; +import { map, Observable } from 'rxjs'; +import { CurrencyService } from './currency.service'; + +@Pipe({ + name: 'currency', +}) +export class CurrencyPipe implements PipeTransform { + currencyService = inject(CurrencyService); + + transform(price: number): Observable { + return this.currencyService.symbol$.pipe(map((s) => `${price}${s}`)); + } +} diff --git a/apps/signal/54-pipe-observable-to-signal/src/app/currency.service.ts b/apps/signal/54-pipe-observable-to-signal/src/app/currency.service.ts new file mode 100644 index 000000000..8ddf570bf --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/app/currency.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, map } from 'rxjs'; + +export interface Currency { + name: string; + code: string; + symbol: string; +} + +export const currency: Currency[] = [ + { name: 'Euro', code: 'EUR', symbol: '€' }, + { name: 'Dollar US', code: 'USD', symbol: 'US$' }, + { name: 'Dollar Australian', code: 'AUD', symbol: 'AU$' }, + { name: 'Pound Sterling', code: 'GBP', symbol: '£' }, + { name: 'Dollar Canadian', code: 'CAD', symbol: 'CAD' }, +]; + +@Injectable() +export class CurrencyService { + private code = new BehaviorSubject('EUR'); + + readonly code$ = this.code.asObservable(); + readonly symbol$ = this.code$.pipe( + map((code) => currency.find((c) => c.code === code)?.symbol ?? code), + ); + + public updateCode(code: string) { + this.code.next(code); + } +} diff --git a/apps/signal/54-pipe-observable-to-signal/src/app/product-row.component.ts b/apps/signal/54-pipe-observable-to-signal/src/app/product-row.component.ts new file mode 100644 index 000000000..7cb3d4e03 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/app/product-row.component.ts @@ -0,0 +1,33 @@ +import { AsyncPipe } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + inject, + Input, +} from '@angular/core'; +import { CurrencyPipe } from './currency.pipe'; +import { CurrencyService } from './currency.service'; +import { Product } from './product.model'; + +@Component({ + selector: 'tr[product-row]', + template: ` + {{ productInfo.name }} + {{ productInfo.priceA | currency | async }} + {{ productInfo.priceB | currency | async }} + {{ productInfo.priceC | currency | async }} + `, + imports: [AsyncPipe, CurrencyPipe], + providers: [CurrencyService], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ProductRowComponent { + protected productInfo!: Product; + + @Input({ required: true }) set product(product: Product) { + this.currencyService.updateCode(product.currencyCode); + this.productInfo = product; + } + + currencyService = inject(CurrencyService); +} diff --git a/apps/signal/54-pipe-observable-to-signal/src/app/product.model.ts b/apps/signal/54-pipe-observable-to-signal/src/app/product.model.ts new file mode 100644 index 000000000..174e7dc77 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/app/product.model.ts @@ -0,0 +1,55 @@ +export interface Product { + name: string; + priceA: number; + priceB: number; + priceC: number; + currencyCode: string; +} + +export const products: Product[] = [ + { + name: 'bike', + priceA: 1000, + priceB: 2000, + priceC: 2200, + currencyCode: 'USD', + }, + { name: 'tent', priceA: 112, priceB: 120, priceC: 41, currencyCode: 'EUR' }, + { + name: 'sofa', + priceA: 500, + priceB: 422, + priceC: 5000, + currencyCode: 'EUR', + }, + { + name: 'watch', + priceA: 50, + priceB: 130, + priceC: 150, + currencyCode: 'AUD', + }, + { + name: 'computer', + priceA: 1000, + priceB: 2200, + priceC: 3500, + currencyCode: 'GBP', + }, + { name: 'mug', priceA: 10, priceB: 15, priceC: 20, currencyCode: 'EUR' }, + { + name: 'headset', + priceA: 100, + priceB: 150, + priceC: 220, + currencyCode: 'CAD', + }, + { name: 'cable', priceA: 5, priceB: 10, priceC: 15, currencyCode: 'EUR' }, + { + name: 'table', + priceA: 100, + priceB: 20, + priceC: 500, + currencyCode: 'EUR', + }, +]; diff --git a/apps/testing/input-output/src/assets/.gitkeep b/apps/signal/54-pipe-observable-to-signal/src/assets/.gitkeep similarity index 100% rename from apps/testing/input-output/src/assets/.gitkeep rename to apps/signal/54-pipe-observable-to-signal/src/assets/.gitkeep diff --git a/apps/testing/todos-list/src/favicon.ico b/apps/signal/54-pipe-observable-to-signal/src/favicon.ico similarity index 100% rename from apps/testing/todos-list/src/favicon.ico rename to apps/signal/54-pipe-observable-to-signal/src/favicon.ico diff --git a/apps/signal/54-pipe-observable-to-signal/src/index.html b/apps/signal/54-pipe-observable-to-signal/src/index.html new file mode 100644 index 000000000..997f94663 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-pipe-observable-to-signal + + + + + + + + diff --git a/apps/signal/54-pipe-observable-to-signal/src/main.ts b/apps/signal/54-pipe-observable-to-signal/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/signal/54-pipe-observable-to-signal/src/styles.scss b/apps/signal/54-pipe-observable-to-signal/src/styles.scss new file mode 100644 index 000000000..552f97df9 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/src/styles.scss @@ -0,0 +1,26 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ +table { + width: 100%; +} + +table thead > tr > th { + text-align: left; + padding: 1rem 1rem; + border: 1px solid #dee2e6; + border-width: 0 0 1px 0; + font-weight: 700; + color: #343a40; + background: #f8f9fa; + transition: box-shadow 0.2s; +} + +table tbody > tr > td { + text-align: left; + border: 1px solid #dee2e6; + border-width: 0 0 1px 0; + padding: 1rem 1rem; +} diff --git a/apps/signal/54-pipe-observable-to-signal/tailwind.config.js b/apps/signal/54-pipe-observable-to-signal/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/54-pipe-observable-to-signal/tsconfig.app.json b/apps/signal/54-pipe-observable-to-signal/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/54-pipe-observable-to-signal/tsconfig.editor.json b/apps/signal/54-pipe-observable-to-signal/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/54-pipe-observable-to-signal/tsconfig.json b/apps/signal/54-pipe-observable-to-signal/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/signal/54-pipe-observable-to-signal/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/signal/56-forms-and-signal/.eslintrc.json b/apps/signal/56-forms-and-signal/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/signal/56-forms-and-signal/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/signal/56-forms-and-signal/README.md b/apps/signal/56-forms-and-signal/README.md new file mode 100644 index 000000000..ba5def1f0 --- /dev/null +++ b/apps/signal/56-forms-and-signal/README.md @@ -0,0 +1,13 @@ +# forms and signal + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve signal-forms-and-signal +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/signal/56-forms-and-signal/). diff --git a/apps/signal/56-forms-and-signal/project.json b/apps/signal/56-forms-and-signal/project.json new file mode 100644 index 000000000..596afbb32 --- /dev/null +++ b/apps/signal/56-forms-and-signal/project.json @@ -0,0 +1,72 @@ +{ + "name": "signal-forms-and-signal", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/signal/56-forms-and-signal/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/signal/56-forms-and-signal", + "index": "apps/signal/56-forms-and-signal/src/index.html", + "browser": "apps/signal/56-forms-and-signal/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/signal/56-forms-and-signal/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/signal/56-forms-and-signal/public" + } + ], + "styles": ["apps/signal/56-forms-and-signal/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "signal-forms-and-signal:build:production" + }, + "development": { + "buildTarget": "signal-forms-and-signal:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "signal-forms-and-signal:build" + } + } + } +} diff --git a/apps/typescript/enums-vs-union-types/src/favicon.ico b/apps/signal/56-forms-and-signal/public/favicon.ico similarity index 100% rename from apps/typescript/enums-vs-union-types/src/favicon.ico rename to apps/signal/56-forms-and-signal/public/favicon.ico diff --git a/apps/signal/56-forms-and-signal/src/app/app.component.ts b/apps/signal/56-forms-and-signal/src/app/app.component.ts new file mode 100644 index 000000000..d6690ea9a --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/app.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet], + selector: 'app-root', + template: ` +

Shop

+
+ +
+ `, + host: { + class: 'w-full flex justify-center flex-col items-center p-4 gap-10', + }, +}) +export class AppComponent {} diff --git a/apps/signal/56-forms-and-signal/src/app/app.config.ts b/apps/signal/56-forms-and-signal/src/app/app.config.ts new file mode 100644 index 000000000..9cebc385d --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter, withComponentInputBinding } from '@angular/router'; +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(routes, withComponentInputBinding()), + ], +}; diff --git a/apps/signal/56-forms-and-signal/src/app/app.routes.ts b/apps/signal/56-forms-and-signal/src/app/app.routes.ts new file mode 100644 index 000000000..091c56d90 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/app.routes.ts @@ -0,0 +1,29 @@ +import { Routes } from '@angular/router'; + +export const routes: Routes = [ + { + path: '', + redirectTo: 'dashboard', + pathMatch: 'full', + }, + { + path: 'dashboard', + loadComponent: () => import('./dashboard.component'), + }, + { + path: 'order', + loadComponent: () => import('./order.component'), + }, + { + path: 'checkout', + loadComponent: () => import('./checkout.component'), + }, + { + path: 'payment', + loadComponent: () => import('./payment.component'), + }, + { + path: '**', + redirectTo: 'dashboard', + }, +]; diff --git a/apps/signal/56-forms-and-signal/src/app/checkout.component.ts b/apps/signal/56-forms-and-signal/src/app/checkout.component.ts new file mode 100644 index 000000000..f9d831088 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/checkout.component.ts @@ -0,0 +1,55 @@ +import { + ChangeDetectionStrategy, + Component, + computed, + input, +} from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { products } from './products'; + +@Component({ + selector: 'app-dashboard', + imports: [RouterLink], + template: ` +

Checkout

+ +
+
Your order:
+
+ {{ quantity() }} x {{ product()?.name }}: {{ product()?.price }}€ +
+
+ +
Billing Information
+
...
+
...
+
...
+
...
+
...
+ + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class DashboardComponent { + quantity = input(1); + productId = input('1'); + + product = computed(() => + products.find((product) => product.id === this.productId()), + ); + totalWithVAT = computed( + () => this.quantity() * (this.product()?.price ?? 0) * 1.21, + ); +} diff --git a/apps/signal/56-forms-and-signal/src/app/dashboard.component.ts b/apps/signal/56-forms-and-signal/src/app/dashboard.component.ts new file mode 100644 index 000000000..d96fedfd7 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/dashboard.component.ts @@ -0,0 +1,30 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { products } from './products'; + +@Component({ + selector: 'app-dashboard', + imports: [RouterLink], + template: ` +

List of Products

+
    + @for (product of products; track product.id) { +
  • +
    + {{ product.name }} ({{ product.price }}€) + +
    +
  • + } +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class DashboardComponent { + products = products; +} diff --git a/apps/signal/56-forms-and-signal/src/app/order.component.ts b/apps/signal/56-forms-and-signal/src/app/order.component.ts new file mode 100644 index 000000000..2b03ba814 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/order.component.ts @@ -0,0 +1,71 @@ +import { + ChangeDetectionStrategy, + Component, + computed, + input, +} from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { RouterLink } from '@angular/router'; +import { products } from './products'; + +@Component({ + selector: 'app-order', + imports: [RouterLink, ReactiveFormsModule], + template: ` +

Order

+
+
+ + +
+
+
SubTotal
+
{{ totalWithoutVat() }} €
+
+
+
VAT (21%)
+
{{ vat() }} €
+
+
+
Total
+
{{ total() }} €
+
+ +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class OrderComponent { + form = new FormGroup({ + quantity: new FormControl(1, { nonNullable: true }), + }); + + productId = input('1'); + price = computed( + () => products.find((p) => p.id === this.productId())?.price ?? 0, + ); + quantity = toSignal(this.form.controls.quantity.valueChanges, { + initialValue: this.form.getRawValue().quantity, + }); + totalWithoutVat = computed(() => Number(this.price()) * this.quantity()); + vat = computed(() => this.totalWithoutVat() * 0.21); + total = computed(() => this.totalWithoutVat() + this.vat()); +} diff --git a/apps/signal/56-forms-and-signal/src/app/payment.component.ts b/apps/signal/56-forms-and-signal/src/app/payment.component.ts new file mode 100644 index 000000000..800bd6f36 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/payment.component.ts @@ -0,0 +1,18 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; + +@Component({ + selector: 'app-dashboard', + imports: [RouterLink], + template: ` +

Payment Success

+ + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class DashboardComponent {} diff --git a/apps/signal/56-forms-and-signal/src/app/products.ts b/apps/signal/56-forms-and-signal/src/app/products.ts new file mode 100644 index 000000000..a893a5b54 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/app/products.ts @@ -0,0 +1,17 @@ +export const products = [ + { + id: '1', + name: 'Computer', + price: 2000, + }, + { + id: '2', + name: 'Mouse', + price: 40, + }, + { + id: '3', + name: 'Keyboard', + price: 80, + }, +]; diff --git a/apps/signal/56-forms-and-signal/src/index.html b/apps/signal/56-forms-and-signal/src/index.html new file mode 100644 index 000000000..eca231086 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/index.html @@ -0,0 +1,13 @@ + + + + + signal-forms-and-signal + + + + + + + + diff --git a/apps/angular/signal-input/src/main.ts b/apps/signal/56-forms-and-signal/src/main.ts similarity index 100% rename from apps/angular/signal-input/src/main.ts rename to apps/signal/56-forms-and-signal/src/main.ts diff --git a/apps/signal/56-forms-and-signal/src/styles.scss b/apps/signal/56-forms-and-signal/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/signal/56-forms-and-signal/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/signal/56-forms-and-signal/tailwind.config.js b/apps/signal/56-forms-and-signal/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/signal/56-forms-and-signal/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/signal/56-forms-and-signal/tsconfig.app.json b/apps/signal/56-forms-and-signal/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/signal/56-forms-and-signal/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/56-forms-and-signal/tsconfig.editor.json b/apps/signal/56-forms-and-signal/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/signal/56-forms-and-signal/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/signal/56-forms-and-signal/tsconfig.json b/apps/signal/56-forms-and-signal/tsconfig.json new file mode 100644 index 000000000..6566ee3c0 --- /dev/null +++ b/apps/signal/56-forms-and-signal/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/checkbox/.eslintrc.json b/apps/testing/17-router/.eslintrc.json similarity index 100% rename from apps/testing/checkbox/.eslintrc.json rename to apps/testing/17-router/.eslintrc.json diff --git a/apps/testing/17-router/README.md b/apps/testing/17-router/README.md new file mode 100644 index 000000000..fe9a75448 --- /dev/null +++ b/apps/testing/17-router/README.md @@ -0,0 +1,13 @@ +# Router + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve testing-router +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/17-router/). diff --git a/apps/testing/17-router/cypress.config.ts b/apps/testing/17-router/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/testing/17-router/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/testing/input-output/cypress/fixtures/example.json b/apps/testing/17-router/cypress/fixtures/example.json similarity index 100% rename from apps/testing/input-output/cypress/fixtures/example.json rename to apps/testing/17-router/cypress/fixtures/example.json diff --git a/apps/testing/17-router/cypress/support/commands.ts b/apps/testing/17-router/cypress/support/commands.ts new file mode 100644 index 000000000..b5d8a9582 --- /dev/null +++ b/apps/testing/17-router/cypress/support/commands.ts @@ -0,0 +1,25 @@ +/// +import { mount } from 'cypress/angular'; + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + mount: typeof mount; + } + } +} + +Cypress.Commands.add('mount', mount); diff --git a/apps/testing/router-outlet/cypress/support/component-index.html b/apps/testing/17-router/cypress/support/component-index.html similarity index 100% rename from apps/testing/router-outlet/cypress/support/component-index.html rename to apps/testing/17-router/cypress/support/component-index.html diff --git a/apps/testing/input-output/cypress/support/component.ts b/apps/testing/17-router/cypress/support/component.ts similarity index 100% rename from apps/testing/input-output/cypress/support/component.ts rename to apps/testing/17-router/cypress/support/component.ts diff --git a/apps/testing/input-output/cypress/tsconfig.json b/apps/testing/17-router/cypress/tsconfig.json similarity index 100% rename from apps/testing/input-output/cypress/tsconfig.json rename to apps/testing/17-router/cypress/tsconfig.json diff --git a/apps/testing/17-router/jest.config.ts b/apps/testing/17-router/jest.config.ts new file mode 100644 index 000000000..5013c9afd --- /dev/null +++ b/apps/testing/17-router/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-router', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: {}, + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/17-router/project.json b/apps/testing/17-router/project.json new file mode 100644 index 000000000..dba3c0666 --- /dev/null +++ b/apps/testing/17-router/project.json @@ -0,0 +1,97 @@ +{ + "name": "testing-router", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/testing/17-router/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/17-router", + "index": "apps/testing/17-router/src/index.html", + "main": "apps/testing/17-router/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/17-router/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/testing/17-router/src/favicon.ico", + "apps/testing/17-router/src/assets" + ], + "styles": ["apps/testing/17-router/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-router:build:production" + }, + "development": { + "buildTarget": "testing-router:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-router:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/testing/17-router/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-router:build" + } + } + } +} diff --git a/apps/testing/router-outlet/src/app/app.component.cy.ts b/apps/testing/17-router/src/app/app.component.cy.ts similarity index 100% rename from apps/testing/router-outlet/src/app/app.component.cy.ts rename to apps/testing/17-router/src/app/app.component.cy.ts diff --git a/apps/testing/router-outlet/src/app/app.component.spec.ts b/apps/testing/17-router/src/app/app.component.spec.ts similarity index 100% rename from apps/testing/router-outlet/src/app/app.component.spec.ts rename to apps/testing/17-router/src/app/app.component.spec.ts diff --git a/apps/testing/17-router/src/app/app.component.ts b/apps/testing/17-router/src/app/app.component.ts new file mode 100644 index 000000000..cc6298f17 --- /dev/null +++ b/apps/testing/17-router/src/app/app.component.ts @@ -0,0 +1,41 @@ +import { Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + styles: [ + ` + h1 { + margin-bottom: 0; + } + nav a { + padding: 1rem; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #e8e8e8; + color: #3d3d3d; + border-radius: 4px; + margin-bottom: 10px; + } + nav a:hover { + color: white; + background-color: #42545c; + } + nav a.active { + background-color: black; + } + `, + ], + template: ` +

Library

+ + + + + `, +}) +export class AppComponent {} diff --git a/apps/testing/router-outlet/src/app/app.config.ts b/apps/testing/17-router/src/app/app.config.ts similarity index 100% rename from apps/testing/router-outlet/src/app/app.config.ts rename to apps/testing/17-router/src/app/app.config.ts diff --git a/apps/testing/router-outlet/src/app/app.routes.ts b/apps/testing/17-router/src/app/app.routes.ts similarity index 100% rename from apps/testing/router-outlet/src/app/app.routes.ts rename to apps/testing/17-router/src/app/app.routes.ts diff --git a/apps/testing/router-outlet/src/app/book.guard.ts b/apps/testing/17-router/src/app/book.guard.ts similarity index 100% rename from apps/testing/router-outlet/src/app/book.guard.ts rename to apps/testing/17-router/src/app/book.guard.ts diff --git a/apps/testing/router-outlet/src/app/book.model.ts b/apps/testing/17-router/src/app/book.model.ts similarity index 100% rename from apps/testing/router-outlet/src/app/book.model.ts rename to apps/testing/17-router/src/app/book.model.ts diff --git a/apps/testing/router-outlet/src/app/no-book-search.component.ts b/apps/testing/17-router/src/app/no-book-search.component.ts similarity index 92% rename from apps/testing/router-outlet/src/app/no-book-search.component.ts rename to apps/testing/17-router/src/app/no-book-search.component.ts index 17d6b97d7..d16c7478d 100644 --- a/apps/testing/router-outlet/src/app/no-book-search.component.ts +++ b/apps/testing/17-router/src/app/no-book-search.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ - standalone: true, template: `
No book found for this search
`, diff --git a/apps/testing/router-outlet/src/app/search.component.ts b/apps/testing/17-router/src/app/search.component.ts similarity index 78% rename from apps/testing/router-outlet/src/app/search.component.ts rename to apps/testing/17-router/src/app/search.component.ts index b6f8666c3..b35db308c 100644 --- a/apps/testing/router-outlet/src/app/search.component.ts +++ b/apps/testing/17-router/src/app/search.component.ts @@ -1,12 +1,10 @@ -import { NgFor, NgIf } from '@angular/common'; import { ChangeDetectionStrategy, Component } from '@angular/core'; import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; -import { RouterLink } from '@angular/router'; +import { RouterLink, RouterLinkActive } from '@angular/router'; import { availableBooks } from './book.model'; @Component({ - standalone: true, - imports: [ReactiveFormsModule, RouterLink, NgFor, NgIf], + imports: [ReactiveFormsModule, RouterLink, RouterLinkActive], styles: [ ` :host { @@ -39,9 +37,9 @@ import { availableBooks } from './book.model'; name="bookName" [formControl]="searchBook" required /> -
- Search criteria is required! -
+ @if (searchBook.errors) { +
Search criteria is required!
+ }
`, diff --git a/apps/testing/17-router/src/app/shelf.component.ts b/apps/testing/17-router/src/app/shelf.component.ts new file mode 100644 index 000000000..238d9836c --- /dev/null +++ b/apps/testing/17-router/src/app/shelf.component.ts @@ -0,0 +1,30 @@ +import { AsyncPipe } from '@angular/common'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { map } from 'rxjs'; +import { availableBooks } from './book.model'; + +@Component({ + selector: 'app-shelf', + imports: [AsyncPipe], + template: ` +
    + @for (book of books | async; track book) { +
  • Borrowed Book: {{ book.name }} by {{ book.author }}
  • + } +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export default class ShelfComponent { + readonly books = inject(ActivatedRoute).queryParams.pipe( + map((params) => params?.['book'].toLowerCase()), + map((param) => + availableBooks.filter( + (b) => + b.name.toLowerCase().includes(param) || + b.author.toLowerCase().includes(param), + ), + ), + ); +} diff --git a/apps/testing/modal/src/assets/.gitkeep b/apps/testing/17-router/src/assets/.gitkeep similarity index 100% rename from apps/testing/modal/src/assets/.gitkeep rename to apps/testing/17-router/src/assets/.gitkeep diff --git a/apps/typescript/overload/src/favicon.ico b/apps/testing/17-router/src/favicon.ico similarity index 100% rename from apps/typescript/overload/src/favicon.ico rename to apps/testing/17-router/src/favicon.ico diff --git a/apps/testing/17-router/src/index.html b/apps/testing/17-router/src/index.html new file mode 100644 index 000000000..80ec9bf77 --- /dev/null +++ b/apps/testing/17-router/src/index.html @@ -0,0 +1,13 @@ + + + + + testing-router + + + + + + + + diff --git a/apps/testing/17-router/src/main.ts b/apps/testing/17-router/src/main.ts new file mode 100644 index 000000000..4fcb1ec76 --- /dev/null +++ b/apps/testing/17-router/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; + +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/performance/scroll-cd/src/styles.scss b/apps/testing/17-router/src/styles.scss similarity index 100% rename from apps/performance/scroll-cd/src/styles.scss rename to apps/testing/17-router/src/styles.scss diff --git a/apps/testing/17-router/src/test-setup.ts b/apps/testing/17-router/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/17-router/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/17-router/tsconfig.app.json b/apps/testing/17-router/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/testing/17-router/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/testing/checkbox/tsconfig.editor.json b/apps/testing/17-router/tsconfig.editor.json similarity index 100% rename from apps/testing/checkbox/tsconfig.editor.json rename to apps/testing/17-router/tsconfig.editor.json diff --git a/apps/testing/17-router/tsconfig.json b/apps/testing/17-router/tsconfig.json new file mode 100644 index 000000000..2316dadd3 --- /dev/null +++ b/apps/testing/17-router/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/17-router/tsconfig.spec.json b/apps/testing/17-router/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/17-router/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/nested/.eslintrc.json b/apps/testing/18-nested-components/.eslintrc.json similarity index 100% rename from apps/testing/nested/.eslintrc.json rename to apps/testing/18-nested-components/.eslintrc.json diff --git a/apps/testing/18-nested-components/README.md b/apps/testing/18-nested-components/README.md new file mode 100644 index 000000000..659b9e365 --- /dev/null +++ b/apps/testing/18-nested-components/README.md @@ -0,0 +1,13 @@ +# Nested Components + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve testing-nested-components +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/18-nested-comp/). diff --git a/apps/testing/18-nested-components/cypress.config.ts b/apps/testing/18-nested-components/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/testing/18-nested-components/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/testing/modal/cypress/fixtures/example.json b/apps/testing/18-nested-components/cypress/fixtures/example.json similarity index 100% rename from apps/testing/modal/cypress/fixtures/example.json rename to apps/testing/18-nested-components/cypress/fixtures/example.json diff --git a/apps/testing/18-nested-components/cypress/support/commands.ts b/apps/testing/18-nested-components/cypress/support/commands.ts new file mode 100644 index 000000000..b5d8a9582 --- /dev/null +++ b/apps/testing/18-nested-components/cypress/support/commands.ts @@ -0,0 +1,25 @@ +/// +import { mount } from 'cypress/angular'; + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + mount: typeof mount; + } + } +} + +Cypress.Commands.add('mount', mount); diff --git a/apps/testing/nested/cypress/support/component-index.html b/apps/testing/18-nested-components/cypress/support/component-index.html similarity index 100% rename from apps/testing/nested/cypress/support/component-index.html rename to apps/testing/18-nested-components/cypress/support/component-index.html diff --git a/apps/testing/modal/cypress/support/component.ts b/apps/testing/18-nested-components/cypress/support/component.ts similarity index 100% rename from apps/testing/modal/cypress/support/component.ts rename to apps/testing/18-nested-components/cypress/support/component.ts diff --git a/apps/testing/modal/cypress/tsconfig.json b/apps/testing/18-nested-components/cypress/tsconfig.json similarity index 100% rename from apps/testing/modal/cypress/tsconfig.json rename to apps/testing/18-nested-components/cypress/tsconfig.json diff --git a/apps/testing/18-nested-components/jest.config.ts b/apps/testing/18-nested-components/jest.config.ts new file mode 100644 index 000000000..542fc897d --- /dev/null +++ b/apps/testing/18-nested-components/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-nested-components', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/18-nested-components/project.json b/apps/testing/18-nested-components/project.json new file mode 100644 index 000000000..aabd0f2db --- /dev/null +++ b/apps/testing/18-nested-components/project.json @@ -0,0 +1,97 @@ +{ + "name": "testing-nested-components", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/testing/18-nested-components/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/18-nested-components", + "index": "apps/testing/18-nested-components/src/index.html", + "main": "apps/testing/18-nested-components/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/18-nested-components/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/testing/18-nested-components/src/favicon.ico", + "apps/testing/18-nested-components/src/assets" + ], + "styles": ["apps/testing/18-nested-components/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-nested-components:build:production" + }, + "development": { + "buildTarget": "testing-nested-components:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-nested-components:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/testing/18-nested-components/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-nested-components:build" + } + } + } +} diff --git a/apps/testing/18-nested-components/src/app/app.component.ts b/apps/testing/18-nested-components/src/app/app.component.ts new file mode 100644 index 000000000..84b0df68a --- /dev/null +++ b/apps/testing/18-nested-components/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { ChildComponent } from './child.component'; + +@Component({ + imports: [ChildComponent], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent {} diff --git a/apps/testing/nested/src/app/child.component.cy.ts b/apps/testing/18-nested-components/src/app/child.component.cy.ts similarity index 100% rename from apps/testing/nested/src/app/child.component.cy.ts rename to apps/testing/18-nested-components/src/app/child.component.cy.ts diff --git a/apps/testing/nested/src/app/child.component.spec.ts b/apps/testing/18-nested-components/src/app/child.component.spec.ts similarity index 100% rename from apps/testing/nested/src/app/child.component.spec.ts rename to apps/testing/18-nested-components/src/app/child.component.spec.ts diff --git a/apps/testing/18-nested-components/src/app/child.component.ts b/apps/testing/18-nested-components/src/app/child.component.ts new file mode 100644 index 000000000..7ead519f4 --- /dev/null +++ b/apps/testing/18-nested-components/src/app/child.component.ts @@ -0,0 +1,81 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + input, + output, +} from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { HttpService } from './http.service'; + +@Component({ + selector: 'app-input', + imports: [ReactiveFormsModule], + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class InputComponent { + title = new FormControl('', { nonNullable: true }); +} + +@Component({ + selector: 'result', + template: ` +

Title is {{ title() }}

+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ResultComponent { + title = input(''); +} + +@Component({ + selector: 'app-button', + template: ` + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ButtonComponent { + validate = output(); +} + +@Component({ + selector: 'app-error', + template: ` +

Title is required !!!

+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ErrorComponent {} + +@Component({ + selector: 'app-child', + imports: [], + template: ` + + + + @if (showError) { + + } + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ChildComponent { + http = inject(HttpService); + + showError = false; + + submit(title: string) { + this.showError = false; + if (title === '') { + this.showError = true; + return; + } + + this.http.sendTitle(title); + } +} diff --git a/apps/testing/nested/src/app/http.service.ts b/apps/testing/18-nested-components/src/app/http.service.ts similarity index 100% rename from apps/testing/nested/src/app/http.service.ts rename to apps/testing/18-nested-components/src/app/http.service.ts diff --git a/apps/testing/nested/src/assets/.gitkeep b/apps/testing/18-nested-components/src/assets/.gitkeep similarity index 100% rename from apps/testing/nested/src/assets/.gitkeep rename to apps/testing/18-nested-components/src/assets/.gitkeep diff --git a/apps/testing/18-nested-components/src/favicon.ico b/apps/testing/18-nested-components/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/18-nested-components/src/favicon.ico differ diff --git a/apps/testing/18-nested-components/src/index.html b/apps/testing/18-nested-components/src/index.html new file mode 100644 index 000000000..5f7055208 --- /dev/null +++ b/apps/testing/18-nested-components/src/index.html @@ -0,0 +1,13 @@ + + + + + testing-nested-components + + + + + + + + diff --git a/apps/testing/18-nested-components/src/main.ts b/apps/testing/18-nested-components/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/testing/18-nested-components/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/rxjs/pipe-bug/src/styles.scss b/apps/testing/18-nested-components/src/styles.scss similarity index 100% rename from apps/rxjs/pipe-bug/src/styles.scss rename to apps/testing/18-nested-components/src/styles.scss diff --git a/apps/testing/18-nested-components/src/test-setup.ts b/apps/testing/18-nested-components/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/18-nested-components/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/18-nested-components/tsconfig.app.json b/apps/testing/18-nested-components/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/testing/18-nested-components/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/testing/input-output/tsconfig.editor.json b/apps/testing/18-nested-components/tsconfig.editor.json similarity index 100% rename from apps/testing/input-output/tsconfig.editor.json rename to apps/testing/18-nested-components/tsconfig.editor.json diff --git a/apps/testing/18-nested-components/tsconfig.json b/apps/testing/18-nested-components/tsconfig.json new file mode 100644 index 000000000..2316dadd3 --- /dev/null +++ b/apps/testing/18-nested-components/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/18-nested-components/tsconfig.spec.json b/apps/testing/18-nested-components/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/18-nested-components/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/create-harness/.eslintrc.json b/apps/testing/19-input-output/.eslintrc.json similarity index 100% rename from apps/testing/create-harness/.eslintrc.json rename to apps/testing/19-input-output/.eslintrc.json diff --git a/apps/testing/input-output/README.md b/apps/testing/19-input-output/README.md similarity index 100% rename from apps/testing/input-output/README.md rename to apps/testing/19-input-output/README.md diff --git a/apps/testing/19-input-output/cypress.config.ts b/apps/testing/19-input-output/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/testing/19-input-output/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/testing/nested/cypress/fixtures/example.json b/apps/testing/19-input-output/cypress/fixtures/example.json similarity index 100% rename from apps/testing/nested/cypress/fixtures/example.json rename to apps/testing/19-input-output/cypress/fixtures/example.json diff --git a/apps/testing/19-input-output/cypress/support/commands.ts b/apps/testing/19-input-output/cypress/support/commands.ts new file mode 100644 index 000000000..b5d8a9582 --- /dev/null +++ b/apps/testing/19-input-output/cypress/support/commands.ts @@ -0,0 +1,25 @@ +/// +import { mount } from 'cypress/angular'; + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + mount: typeof mount; + } + } +} + +Cypress.Commands.add('mount', mount); diff --git a/apps/testing/input-output/cypress/support/component-index.html b/apps/testing/19-input-output/cypress/support/component-index.html similarity index 100% rename from apps/testing/input-output/cypress/support/component-index.html rename to apps/testing/19-input-output/cypress/support/component-index.html diff --git a/apps/testing/nested/cypress/support/component.ts b/apps/testing/19-input-output/cypress/support/component.ts similarity index 100% rename from apps/testing/nested/cypress/support/component.ts rename to apps/testing/19-input-output/cypress/support/component.ts diff --git a/apps/testing/nested/cypress/tsconfig.json b/apps/testing/19-input-output/cypress/tsconfig.json similarity index 100% rename from apps/testing/nested/cypress/tsconfig.json rename to apps/testing/19-input-output/cypress/tsconfig.json diff --git a/apps/testing/19-input-output/jest.config.ts b/apps/testing/19-input-output/jest.config.ts new file mode 100644 index 000000000..1d602a293 --- /dev/null +++ b/apps/testing/19-input-output/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-input-output', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/19-input-output/project.json b/apps/testing/19-input-output/project.json new file mode 100644 index 000000000..ae92fe796 --- /dev/null +++ b/apps/testing/19-input-output/project.json @@ -0,0 +1,97 @@ +{ + "name": "testing-input-output", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/testing/19-input-output/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/19-input-output", + "index": "apps/testing/19-input-output/src/index.html", + "main": "apps/testing/19-input-output/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/19-input-output/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/testing/19-input-output/src/favicon.ico", + "apps/testing/19-input-output/src/assets" + ], + "styles": ["apps/testing/19-input-output/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-input-output:build:production" + }, + "development": { + "buildTarget": "testing-input-output:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-input-output:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/testing/19-input-output/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-input-output:build" + } + } + } +} diff --git a/apps/testing/19-input-output/src/app/app.component.ts b/apps/testing/19-input-output/src/app/app.component.ts new file mode 100644 index 000000000..7e9e0f78a --- /dev/null +++ b/apps/testing/19-input-output/src/app/app.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { CounterComponent } from './counter.component'; + +@Component({ + imports: [CounterComponent], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent { + log(counter: number) { + console.log('output log', counter); + } +} diff --git a/apps/testing/input-output/src/app/counter.component.cy.ts b/apps/testing/19-input-output/src/app/counter.component.cy.ts similarity index 100% rename from apps/testing/input-output/src/app/counter.component.cy.ts rename to apps/testing/19-input-output/src/app/counter.component.cy.ts diff --git a/apps/testing/input-output/src/app/counter.component.spec.ts b/apps/testing/19-input-output/src/app/counter.component.spec.ts similarity index 100% rename from apps/testing/input-output/src/app/counter.component.spec.ts rename to apps/testing/19-input-output/src/app/counter.component.spec.ts diff --git a/apps/testing/19-input-output/src/app/counter.component.ts b/apps/testing/19-input-output/src/app/counter.component.ts new file mode 100644 index 000000000..df1eed103 --- /dev/null +++ b/apps/testing/19-input-output/src/app/counter.component.ts @@ -0,0 +1,32 @@ +import { + ChangeDetectionStrategy, + Component, + input, + linkedSignal, + output, +} from '@angular/core'; + +@Component({ + selector: 'app-counter', + template: ` +

Counter: {{ counter() }}

+ + + + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CounterComponent { + initialValue = input.required(); + public counter = linkedSignal(() => this.initialValue()); + + send = output(); + + public increment = () => { + this.counter.set(this.counter() + 1); + }; + + public decrement = () => { + this.counter.set(this.counter() - 1); + }; +} diff --git a/apps/testing/router-outlet/src/assets/.gitkeep b/apps/testing/19-input-output/src/assets/.gitkeep similarity index 100% rename from apps/testing/router-outlet/src/assets/.gitkeep rename to apps/testing/19-input-output/src/assets/.gitkeep diff --git a/apps/testing/19-input-output/src/favicon.ico b/apps/testing/19-input-output/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/19-input-output/src/favicon.ico differ diff --git a/apps/testing/19-input-output/src/index.html b/apps/testing/19-input-output/src/index.html new file mode 100644 index 000000000..a5cd1c5da --- /dev/null +++ b/apps/testing/19-input-output/src/index.html @@ -0,0 +1,13 @@ + + + + + testing-input-ouput + + + + + + + + diff --git a/apps/testing/19-input-output/src/main.ts b/apps/testing/19-input-output/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/testing/19-input-output/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/testing/input-output/src/styles.scss b/apps/testing/19-input-output/src/styles.scss similarity index 100% rename from apps/testing/input-output/src/styles.scss rename to apps/testing/19-input-output/src/styles.scss diff --git a/apps/testing/19-input-output/src/test-setup.ts b/apps/testing/19-input-output/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/19-input-output/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/19-input-output/tsconfig.app.json b/apps/testing/19-input-output/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/testing/19-input-output/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/testing/modal/tsconfig.editor.json b/apps/testing/19-input-output/tsconfig.editor.json similarity index 100% rename from apps/testing/modal/tsconfig.editor.json rename to apps/testing/19-input-output/tsconfig.editor.json diff --git a/apps/testing/19-input-output/tsconfig.json b/apps/testing/19-input-output/tsconfig.json new file mode 100644 index 000000000..2316dadd3 --- /dev/null +++ b/apps/testing/19-input-output/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/19-input-output/tsconfig.spec.json b/apps/testing/19-input-output/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/19-input-output/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/harness/.eslintrc.json b/apps/testing/20-modal/.eslintrc.json similarity index 100% rename from apps/testing/harness/.eslintrc.json rename to apps/testing/20-modal/.eslintrc.json diff --git a/apps/testing/modal/README.md b/apps/testing/20-modal/README.md similarity index 100% rename from apps/testing/modal/README.md rename to apps/testing/20-modal/README.md diff --git a/apps/testing/20-modal/cypress.config.ts b/apps/testing/20-modal/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/testing/20-modal/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/testing/router-outlet/cypress/fixtures/example.json b/apps/testing/20-modal/cypress/fixtures/example.json similarity index 100% rename from apps/testing/router-outlet/cypress/fixtures/example.json rename to apps/testing/20-modal/cypress/fixtures/example.json diff --git a/apps/testing/20-modal/cypress/support/commands.ts b/apps/testing/20-modal/cypress/support/commands.ts new file mode 100644 index 000000000..b5d8a9582 --- /dev/null +++ b/apps/testing/20-modal/cypress/support/commands.ts @@ -0,0 +1,25 @@ +/// +import { mount } from 'cypress/angular'; + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + mount: typeof mount; + } + } +} + +Cypress.Commands.add('mount', mount); diff --git a/apps/testing/modal/cypress/support/component-index.html b/apps/testing/20-modal/cypress/support/component-index.html similarity index 100% rename from apps/testing/modal/cypress/support/component-index.html rename to apps/testing/20-modal/cypress/support/component-index.html diff --git a/apps/testing/router-outlet/cypress/support/component.ts b/apps/testing/20-modal/cypress/support/component.ts similarity index 100% rename from apps/testing/router-outlet/cypress/support/component.ts rename to apps/testing/20-modal/cypress/support/component.ts diff --git a/apps/testing/router-outlet/cypress/tsconfig.json b/apps/testing/20-modal/cypress/tsconfig.json similarity index 100% rename from apps/testing/router-outlet/cypress/tsconfig.json rename to apps/testing/20-modal/cypress/tsconfig.json diff --git a/apps/testing/20-modal/jest.config.ts b/apps/testing/20-modal/jest.config.ts new file mode 100644 index 000000000..042e95ce0 --- /dev/null +++ b/apps/testing/20-modal/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-modal', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/20-modal/project.json b/apps/testing/20-modal/project.json new file mode 100644 index 000000000..8892cc51c --- /dev/null +++ b/apps/testing/20-modal/project.json @@ -0,0 +1,100 @@ +{ + "name": "testing-modal", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/testing/20-modal/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/20-modal", + "index": "apps/testing/20-modal/src/index.html", + "main": "apps/testing/20-modal/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/20-modal/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/testing/20-modal/src/favicon.ico", + "apps/testing/20-modal/src/assets" + ], + "styles": [ + "apps/testing/20-modal/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-modal:build:production" + }, + "development": { + "buildTarget": "testing-modal:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-modal:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/testing/20-modal/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-modal:build" + } + } + } +} diff --git a/apps/testing/modal/src/app/app.component.cy.ts b/apps/testing/20-modal/src/app/app.component.cy.ts similarity index 100% rename from apps/testing/modal/src/app/app.component.cy.ts rename to apps/testing/20-modal/src/app/app.component.cy.ts diff --git a/apps/testing/modal/src/app/app.component.spec.ts b/apps/testing/20-modal/src/app/app.component.spec.ts similarity index 100% rename from apps/testing/modal/src/app/app.component.spec.ts rename to apps/testing/20-modal/src/app/app.component.spec.ts diff --git a/apps/testing/20-modal/src/app/app.component.ts b/apps/testing/20-modal/src/app/app.component.ts new file mode 100644 index 000000000..d5f35b4bf --- /dev/null +++ b/apps/testing/20-modal/src/app/app.component.ts @@ -0,0 +1,64 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { BehaviorSubject } from 'rxjs'; +import { ErrorDialog } from './error.dialog'; +import { ProfilConfirmationDialog } from './profil-confirmation.dialog'; +@Component({ + imports: [ + ReactiveFormsModule, + MatDialogModule, + MatFormFieldModule, + MatInputModule, + MatButtonModule, + AsyncPipe, + ], + selector: 'app-root', + host: { + class: 'p-4 block flex gap-4 items-center', + }, + template: ` + + Name + + + + +
{{ result$ | async }}
+ `, +}) +export class AppComponent { + private modal = inject(MatDialog); + private result = new BehaviorSubject(''); + result$ = this.result.asObservable(); + + name = new FormControl('', { nonNullable: true }); + + confirm() { + if (!this.name.value) { + this.modal.open(ErrorDialog); + return; + } + + this.modal + .open(ProfilConfirmationDialog, { + data: { + name: this.name.value, + }, + }) + .afterClosed() + .subscribe((result) => + this.result.next( + result ? 'Name has been submitted' : 'Name is invalid !!', + ), + ); + } +} diff --git a/apps/testing/modal/src/app/app.config.ts b/apps/testing/20-modal/src/app/app.config.ts similarity index 100% rename from apps/testing/modal/src/app/app.config.ts rename to apps/testing/20-modal/src/app/app.config.ts diff --git a/apps/testing/modal/src/app/error.dialog.ts b/apps/testing/20-modal/src/app/error.dialog.ts similarity index 96% rename from apps/testing/modal/src/app/error.dialog.ts rename to apps/testing/20-modal/src/app/error.dialog.ts index 38412ba5e..251d5d513 100644 --- a/apps/testing/modal/src/app/error.dialog.ts +++ b/apps/testing/20-modal/src/app/error.dialog.ts @@ -4,7 +4,6 @@ import { MatButtonModule } from '@angular/material/button'; import { MatDialogModule } from '@angular/material/dialog'; @Component({ - standalone: true, imports: [MatButtonModule, MatDialogModule], template: `

Error

diff --git a/apps/testing/modal/src/app/profil-confirmation.dialog.ts b/apps/testing/20-modal/src/app/profil-confirmation.dialog.ts similarity index 97% rename from apps/testing/modal/src/app/profil-confirmation.dialog.ts rename to apps/testing/20-modal/src/app/profil-confirmation.dialog.ts index 6af2d41dd..e77211e24 100644 --- a/apps/testing/modal/src/app/profil-confirmation.dialog.ts +++ b/apps/testing/20-modal/src/app/profil-confirmation.dialog.ts @@ -4,7 +4,6 @@ import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; @Component({ - standalone: true, imports: [MatButtonModule, MatDialogModule], template: `

Profil

diff --git a/apps/testing/table/src/assets/.gitkeep b/apps/testing/20-modal/src/assets/.gitkeep similarity index 100% rename from apps/testing/table/src/assets/.gitkeep rename to apps/testing/20-modal/src/assets/.gitkeep diff --git a/apps/testing/20-modal/src/favicon.ico b/apps/testing/20-modal/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/20-modal/src/favicon.ico differ diff --git a/apps/testing/20-modal/src/index.html b/apps/testing/20-modal/src/index.html new file mode 100644 index 000000000..362733ce1 --- /dev/null +++ b/apps/testing/20-modal/src/index.html @@ -0,0 +1,13 @@ + + + + + testing-modal + + + + + + + + diff --git a/apps/testing/20-modal/src/main.ts b/apps/testing/20-modal/src/main.ts new file mode 100644 index 000000000..4fcb1ec76 --- /dev/null +++ b/apps/testing/20-modal/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; + +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/20-modal/src/styles.scss b/apps/testing/20-modal/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/testing/20-modal/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/testing/20-modal/src/test-setup.ts b/apps/testing/20-modal/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/20-modal/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/20-modal/tailwind.config.js b/apps/testing/20-modal/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/testing/20-modal/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/testing/20-modal/tsconfig.app.json b/apps/testing/20-modal/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/testing/20-modal/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/testing/nested/tsconfig.editor.json b/apps/testing/20-modal/tsconfig.editor.json similarity index 100% rename from apps/testing/nested/tsconfig.editor.json rename to apps/testing/20-modal/tsconfig.editor.json diff --git a/apps/testing/20-modal/tsconfig.json b/apps/testing/20-modal/tsconfig.json new file mode 100644 index 000000000..2316dadd3 --- /dev/null +++ b/apps/testing/20-modal/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/20-modal/tsconfig.spec.json b/apps/testing/20-modal/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/20-modal/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/input-output/.eslintrc.json b/apps/testing/23-harness/.eslintrc.json similarity index 100% rename from apps/testing/input-output/.eslintrc.json rename to apps/testing/23-harness/.eslintrc.json diff --git a/apps/testing/harness/README.md b/apps/testing/23-harness/README.md similarity index 100% rename from apps/testing/harness/README.md rename to apps/testing/23-harness/README.md diff --git a/apps/testing/23-harness/jest.config.ts b/apps/testing/23-harness/jest.config.ts new file mode 100644 index 000000000..f4d97f5e6 --- /dev/null +++ b/apps/testing/23-harness/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-harness', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/23-harness/project.json b/apps/testing/23-harness/project.json new file mode 100644 index 000000000..4da50e6a4 --- /dev/null +++ b/apps/testing/23-harness/project.json @@ -0,0 +1,87 @@ +{ + "name": "testing-harness", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/testing/23-harness/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/23-harness", + "index": "apps/testing/23-harness/src/index.html", + "main": "apps/testing/23-harness/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/23-harness/tsconfig.app.json", + "assets": [ + "apps/testing/23-harness/src/favicon.ico", + "apps/testing/23-harness/src/assets" + ], + "styles": ["apps/testing/23-harness/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-harness:build:production" + }, + "development": { + "buildTarget": "testing-harness:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-harness:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/testing/23-harness/src/app/app.component.ts b/apps/testing/23-harness/src/app/app.component.ts new file mode 100644 index 000000000..7ecf1998d --- /dev/null +++ b/apps/testing/23-harness/src/app/app.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { ChildComponent } from './child.component'; + +@Component({ + imports: [ChildComponent], + selector: 'app-root', + template: ` + + `, + styles: [''], +}) +export class AppComponent {} diff --git a/apps/testing/create-harness/src/app/app.config.ts b/apps/testing/23-harness/src/app/app.config.ts similarity index 100% rename from apps/testing/create-harness/src/app/app.config.ts rename to apps/testing/23-harness/src/app/app.config.ts diff --git a/apps/testing/harness/src/app/child.component.spec.ts b/apps/testing/23-harness/src/app/child.component.spec.ts similarity index 100% rename from apps/testing/harness/src/app/child.component.spec.ts rename to apps/testing/23-harness/src/app/child.component.spec.ts diff --git a/apps/testing/23-harness/src/app/child.component.ts b/apps/testing/23-harness/src/app/child.component.ts new file mode 100644 index 000000000..935f08f89 --- /dev/null +++ b/apps/testing/23-harness/src/app/child.component.ts @@ -0,0 +1,119 @@ +import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatSliderModule } from '@angular/material/slider'; + +@Component({ + selector: 'app-child', + template: ` + + +

Slider configuration

+ +
+ + Value + + + + Min value + + + + Max value + + + + Step size + + +
+ +
+ Show ticks +
+ +
+ Show thumb label +
+ +
+ Disabled +
+
+
+ + + +
+ + + + + +
+
+
+ `, + styles: [ + ` + .mat-mdc-slider { + max-width: 300px; + width: 100%; + } + + .mat-mdc-card + .mat-mdc-card { + margin-top: 8px; + } + `, + ], + imports: [ + MatCardModule, + MatFormFieldModule, + MatInputModule, + FormsModule, + MatCheckboxModule, + MatSliderModule, + MatIconModule, + ], +}) +export class ChildComponent { + disabled = false; + max = 100; + min = 0; + showTicks = false; + step = 1; + thumbLabel = false; + value = 0; + + back() { + if (this.value - this.step >= this.min) { + this.value -= this.step; + } + } + + forward() { + if (this.value + this.step <= this.max) { + this.value += this.step; + } + } +} diff --git a/apps/testing/todos-list/src/assets/.gitkeep b/apps/testing/23-harness/src/assets/.gitkeep similarity index 100% rename from apps/testing/todos-list/src/assets/.gitkeep rename to apps/testing/23-harness/src/assets/.gitkeep diff --git a/apps/testing/23-harness/src/favicon.ico b/apps/testing/23-harness/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/23-harness/src/favicon.ico differ diff --git a/apps/testing/23-harness/src/index.html b/apps/testing/23-harness/src/index.html new file mode 100644 index 000000000..9b55da74f --- /dev/null +++ b/apps/testing/23-harness/src/index.html @@ -0,0 +1,16 @@ + + + + + testing-harness + + + + + + + + + diff --git a/apps/testing/23-harness/src/main.ts b/apps/testing/23-harness/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/testing/23-harness/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/23-harness/src/styles.scss b/apps/testing/23-harness/src/styles.scss new file mode 100644 index 000000000..9a29b71e6 --- /dev/null +++ b/apps/testing/23-harness/src/styles.scss @@ -0,0 +1,29 @@ +@use '@angular/material' as mat; + +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ + +@include mat.elevation-classes(); +@include mat.app-background(); + +$theme-primary: mat.m2-define-palette(mat.$m2-indigo-palette); +$theme-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); + +$theme-warn: mat.m2-define-palette(mat.$m2-red-palette); + +$theme: mat.m2-define-light-theme( + ( + color: ( + primary: $theme-primary, + accent: $theme-accent, + warn: $theme-warn, + ), + typography: mat.m2-define-typography-config(), + ) +); + +@include mat.dialog-theme($theme); +@include mat.all-component-themes($theme); diff --git a/apps/testing/23-harness/src/test-setup.ts b/apps/testing/23-harness/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/23-harness/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/23-harness/tailwind.config.js b/apps/testing/23-harness/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/testing/23-harness/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/testing/23-harness/tsconfig.app.json b/apps/testing/23-harness/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/testing/23-harness/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/testing/harness/tsconfig.editor.json b/apps/testing/23-harness/tsconfig.editor.json similarity index 100% rename from apps/testing/harness/tsconfig.editor.json rename to apps/testing/23-harness/tsconfig.editor.json diff --git a/apps/testing/23-harness/tsconfig.json b/apps/testing/23-harness/tsconfig.json new file mode 100644 index 000000000..2af71c94d --- /dev/null +++ b/apps/testing/23-harness/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/23-harness/tsconfig.spec.json b/apps/testing/23-harness/tsconfig.spec.json new file mode 100644 index 000000000..654297648 --- /dev/null +++ b/apps/testing/23-harness/tsconfig.spec.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "target": "es2016", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/modal/.eslintrc.json b/apps/testing/24-harness-creation/.eslintrc.json similarity index 100% rename from apps/testing/modal/.eslintrc.json rename to apps/testing/24-harness-creation/.eslintrc.json diff --git a/apps/testing/24-harness-creation/README.md b/apps/testing/24-harness-creation/README.md new file mode 100644 index 000000000..928bb1aab --- /dev/null +++ b/apps/testing/24-harness-creation/README.md @@ -0,0 +1,13 @@ +# Harness Creation + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve testing-harness-creation +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/24-harness-creation/). diff --git a/apps/testing/24-harness-creation/jest.config.ts b/apps/testing/24-harness-creation/jest.config.ts new file mode 100644 index 000000000..54d4ff975 --- /dev/null +++ b/apps/testing/24-harness-creation/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-harness-creation', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/24-harness-creation/project.json b/apps/testing/24-harness-creation/project.json new file mode 100644 index 000000000..60b0ddb8b --- /dev/null +++ b/apps/testing/24-harness-creation/project.json @@ -0,0 +1,87 @@ +{ + "name": "testing-harness-creation", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/testing/24-harness-creation/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/24-harness-creation", + "index": "apps/testing/24-harness-creation/src/index.html", + "main": "apps/testing/24-harness-creation/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/24-harness-creation/tsconfig.app.json", + "assets": [ + "apps/testing/24-harness-creation/src/favicon.ico", + "apps/testing/24-harness-creation/src/assets" + ], + "styles": ["apps/testing/24-harness-creation/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-harness-creation:build:production" + }, + "development": { + "buildTarget": "testing-harness-creation:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-harness-creation:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/testing/create-harness/src/app/app.component.spec.ts b/apps/testing/24-harness-creation/src/app/app.component.spec.ts similarity index 100% rename from apps/testing/create-harness/src/app/app.component.spec.ts rename to apps/testing/24-harness-creation/src/app/app.component.spec.ts diff --git a/apps/testing/24-harness-creation/src/app/app.component.ts b/apps/testing/24-harness-creation/src/app/app.component.ts new file mode 100644 index 000000000..b1c16240e --- /dev/null +++ b/apps/testing/24-harness-creation/src/app/app.component.ts @@ -0,0 +1,27 @@ +import { Component, signal } from '@angular/core'; +import { SliderComponent } from './slider.component'; + +@Component({ + imports: [SliderComponent], + selector: 'app-root', + template: ` +

Slider 1: {{ slider1Value() }}

+ +

Slider 2: {{ slider2Value() }}

+

Enabled only if Slider 1 > 20

+ + `, + styles: [''], +}) +export class AppComponent { + slider1Value = signal(10); + slider2Value = signal(0); +} diff --git a/apps/testing/harness/src/app/app.config.ts b/apps/testing/24-harness-creation/src/app/app.config.ts similarity index 100% rename from apps/testing/harness/src/app/app.config.ts rename to apps/testing/24-harness-creation/src/app/app.config.ts diff --git a/apps/testing/24-harness-creation/src/app/slider.component.ts b/apps/testing/24-harness-creation/src/app/slider.component.ts new file mode 100644 index 000000000..28615728f --- /dev/null +++ b/apps/testing/24-harness-creation/src/app/slider.component.ts @@ -0,0 +1,75 @@ +import { Component, input, OnInit, output, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { MatSliderModule } from '@angular/material/slider'; + +@Component({ + selector: 'app-slider', + template: ` + + +
+ + {{ minValue() }} + + + + {{ maxValue() }} + +
+
+
+ `, + styles: [ + ` + .mat-mdc-slider { + max-width: 300px; + width: 100%; + } + + .mat-mdc-card { + margin-top: 8px; + flex-direction: row; + } + `, + ], + imports: [MatCardModule, MatSliderModule, MatIconModule, FormsModule], +}) +export class SliderComponent implements OnInit { + step = input(1); + minValue = input(0); + maxValue = input(100); + disabled = input(false); + + value = signal(0); + valueChange = output(); + + ngOnInit(): void { + this.value.set(this.minValue()); + } + + back() { + if (this.value() - this.step() >= this.minValue()) { + this.value.update((v) => v - this.step()); + } + } + + forward() { + if (this.value() + this.step() <= this.maxValue()) { + this.value.update((v) => v + this.step()); + } + } +} diff --git a/apps/testing/create-harness/src/app/slider.harness.ts b/apps/testing/24-harness-creation/src/app/slider.harness.ts similarity index 100% rename from apps/testing/create-harness/src/app/slider.harness.ts rename to apps/testing/24-harness-creation/src/app/slider.harness.ts diff --git a/apps/typescript/enums-vs-union-types/src/assets/.gitkeep b/apps/testing/24-harness-creation/src/assets/.gitkeep similarity index 100% rename from apps/typescript/enums-vs-union-types/src/assets/.gitkeep rename to apps/testing/24-harness-creation/src/assets/.gitkeep diff --git a/apps/testing/24-harness-creation/src/favicon.ico b/apps/testing/24-harness-creation/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/24-harness-creation/src/favicon.ico differ diff --git a/apps/testing/24-harness-creation/src/index.html b/apps/testing/24-harness-creation/src/index.html new file mode 100644 index 000000000..c66440e5c --- /dev/null +++ b/apps/testing/24-harness-creation/src/index.html @@ -0,0 +1,16 @@ + + + + + testing-harness-creation + + + + + + + + + diff --git a/apps/testing/24-harness-creation/src/main.ts b/apps/testing/24-harness-creation/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/testing/24-harness-creation/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/24-harness-creation/src/styles.scss b/apps/testing/24-harness-creation/src/styles.scss new file mode 100644 index 000000000..1430d2f9b --- /dev/null +++ b/apps/testing/24-harness-creation/src/styles.scss @@ -0,0 +1,30 @@ +/* You can add global styles to this file, and also import other style files */ +@use '@angular/material' as mat; + +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ + +@include mat.elevation-classes(); +@include mat.app-background(); + +$theme-primary: mat.m2-define-palette(mat.$m2-indigo-palette); +$theme-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); + +$theme-warn: mat.m2-define-palette(mat.$m2-red-palette); + +$theme: mat.m2-define-light-theme( + ( + color: ( + primary: $theme-primary, + accent: $theme-accent, + warn: $theme-warn, + ), + typography: mat.m2-define-typography-config(), + ) +); + +@include mat.dialog-theme($theme); +@include mat.all-component-themes($theme); diff --git a/apps/testing/24-harness-creation/src/test-setup.ts b/apps/testing/24-harness-creation/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/24-harness-creation/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/24-harness-creation/tailwind.config.js b/apps/testing/24-harness-creation/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/testing/24-harness-creation/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/testing/24-harness-creation/tsconfig.app.json b/apps/testing/24-harness-creation/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/testing/24-harness-creation/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/testing/create-harness/tsconfig.editor.json b/apps/testing/24-harness-creation/tsconfig.editor.json similarity index 100% rename from apps/testing/create-harness/tsconfig.editor.json rename to apps/testing/24-harness-creation/tsconfig.editor.json diff --git a/apps/testing/24-harness-creation/tsconfig.json b/apps/testing/24-harness-creation/tsconfig.json new file mode 100644 index 000000000..2af71c94d --- /dev/null +++ b/apps/testing/24-harness-creation/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/24-harness-creation/tsconfig.spec.json b/apps/testing/24-harness-creation/tsconfig.spec.json new file mode 100644 index 000000000..654297648 --- /dev/null +++ b/apps/testing/24-harness-creation/tsconfig.spec.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "target": "es2016", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/router-outlet/.eslintrc.json b/apps/testing/28-checkbox/.eslintrc.json similarity index 100% rename from apps/testing/router-outlet/.eslintrc.json rename to apps/testing/28-checkbox/.eslintrc.json diff --git a/apps/testing/checkbox/README.md b/apps/testing/28-checkbox/README.md similarity index 100% rename from apps/testing/checkbox/README.md rename to apps/testing/28-checkbox/README.md diff --git a/apps/testing/28-checkbox/jest.config.ts b/apps/testing/28-checkbox/jest.config.ts new file mode 100644 index 000000000..ce32568a4 --- /dev/null +++ b/apps/testing/28-checkbox/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-checkbox', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/testing/28-checkbox', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/28-checkbox/project.json b/apps/testing/28-checkbox/project.json new file mode 100644 index 000000000..2ef8a3cc1 --- /dev/null +++ b/apps/testing/28-checkbox/project.json @@ -0,0 +1,83 @@ +{ + "name": "testing-checkbox", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/testing/28-checkbox/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/28-checkbox", + "index": "apps/testing/28-checkbox/src/index.html", + "main": "apps/testing/28-checkbox/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/28-checkbox/tsconfig.app.json", + "assets": [ + "apps/testing/28-checkbox/src/favicon.ico", + "apps/testing/28-checkbox/src/assets" + ], + "styles": ["apps/testing/28-checkbox/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-checkbox:build:production" + }, + "development": { + "buildTarget": "testing-checkbox:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-checkbox:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/testing/checkbox/src/app/app.component.spec.ts b/apps/testing/28-checkbox/src/app/app.component.spec.ts similarity index 100% rename from apps/testing/checkbox/src/app/app.component.spec.ts rename to apps/testing/28-checkbox/src/app/app.component.spec.ts diff --git a/apps/testing/28-checkbox/src/app/app.component.ts b/apps/testing/28-checkbox/src/app/app.component.ts new file mode 100644 index 000000000..d23f1700b --- /dev/null +++ b/apps/testing/28-checkbox/src/app/app.component.ts @@ -0,0 +1,28 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` + + + + `, +}) +export class AppComponent { + check = false; + + toggleCheck() { + this.check = !this.check; + } +} diff --git a/apps/typescript/overload/src/assets/.gitkeep b/apps/testing/28-checkbox/src/assets/.gitkeep similarity index 100% rename from apps/typescript/overload/src/assets/.gitkeep rename to apps/testing/28-checkbox/src/assets/.gitkeep diff --git a/apps/testing/28-checkbox/src/favicon.ico b/apps/testing/28-checkbox/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/28-checkbox/src/favicon.ico differ diff --git a/apps/testing/checkbox/src/index.html b/apps/testing/28-checkbox/src/index.html similarity index 100% rename from apps/testing/checkbox/src/index.html rename to apps/testing/28-checkbox/src/index.html diff --git a/apps/testing/28-checkbox/src/main.ts b/apps/testing/28-checkbox/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/testing/28-checkbox/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/testing/28-checkbox/src/styles.scss b/apps/testing/28-checkbox/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/testing/28-checkbox/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/testing/28-checkbox/src/test-setup.ts b/apps/testing/28-checkbox/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/28-checkbox/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/28-checkbox/tailwind.config.js b/apps/testing/28-checkbox/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/testing/28-checkbox/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/testing/28-checkbox/tsconfig.app.json b/apps/testing/28-checkbox/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/testing/28-checkbox/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/testing/router-outlet/tsconfig.editor.json b/apps/testing/28-checkbox/tsconfig.editor.json similarity index 100% rename from apps/testing/router-outlet/tsconfig.editor.json rename to apps/testing/28-checkbox/tsconfig.editor.json diff --git a/apps/testing/28-checkbox/tsconfig.json b/apps/testing/28-checkbox/tsconfig.json new file mode 100644 index 000000000..8eb2c56e2 --- /dev/null +++ b/apps/testing/28-checkbox/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/28-checkbox/tsconfig.spec.json b/apps/testing/28-checkbox/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/28-checkbox/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/table/.eslintrc.json b/apps/testing/29-real-life-application/.eslintrc.json similarity index 100% rename from apps/testing/table/.eslintrc.json rename to apps/testing/29-real-life-application/.eslintrc.json diff --git a/apps/testing/29-real-life-application/README.md b/apps/testing/29-real-life-application/README.md new file mode 100644 index 000000000..8dcfe21e6 --- /dev/null +++ b/apps/testing/29-real-life-application/README.md @@ -0,0 +1,13 @@ +# Real-life Application + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve testing-real-life-application +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/29-real-application/). diff --git a/apps/testing/29-real-life-application/cypress.config.ts b/apps/testing/29-real-life-application/cypress.config.ts new file mode 100644 index 000000000..3738464ee --- /dev/null +++ b/apps/testing/29-real-life-application/cypress.config.ts @@ -0,0 +1,8 @@ +import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + component: { + ...nxComponentTestingPreset(__filename), + }, +}); diff --git a/apps/testing/table/cypress/fixtures/example.json b/apps/testing/29-real-life-application/cypress/fixtures/example.json similarity index 100% rename from apps/testing/table/cypress/fixtures/example.json rename to apps/testing/29-real-life-application/cypress/fixtures/example.json diff --git a/apps/testing/29-real-life-application/cypress/support/commands.ts b/apps/testing/29-real-life-application/cypress/support/commands.ts new file mode 100644 index 000000000..b5d8a9582 --- /dev/null +++ b/apps/testing/29-real-life-application/cypress/support/commands.ts @@ -0,0 +1,25 @@ +/// +import { mount } from 'cypress/angular'; + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + mount: typeof mount; + } + } +} + +Cypress.Commands.add('mount', mount); diff --git a/apps/testing/29-real-life-application/cypress/support/component-index.html b/apps/testing/29-real-life-application/cypress/support/component-index.html new file mode 100644 index 000000000..2315c8b59 --- /dev/null +++ b/apps/testing/29-real-life-application/cypress/support/component-index.html @@ -0,0 +1,12 @@ + + + + + + + testing-real-life-application Components App + + +
+ + diff --git a/apps/testing/table/cypress/support/component.ts b/apps/testing/29-real-life-application/cypress/support/component.ts similarity index 100% rename from apps/testing/table/cypress/support/component.ts rename to apps/testing/29-real-life-application/cypress/support/component.ts diff --git a/apps/testing/table/cypress/tsconfig.json b/apps/testing/29-real-life-application/cypress/tsconfig.json similarity index 100% rename from apps/testing/table/cypress/tsconfig.json rename to apps/testing/29-real-life-application/cypress/tsconfig.json diff --git a/apps/testing/29-real-life-application/jest.config.ts b/apps/testing/29-real-life-application/jest.config.ts new file mode 100644 index 000000000..3e9abb3ac --- /dev/null +++ b/apps/testing/29-real-life-application/jest.config.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +module.exports = { + displayName: 'testing-real-life-application', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/testing/29-real-life-application/project.json b/apps/testing/29-real-life-application/project.json new file mode 100644 index 000000000..25833bf4c --- /dev/null +++ b/apps/testing/29-real-life-application/project.json @@ -0,0 +1,100 @@ +{ + "name": "testing-real-life-application", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/testing/29-real-life-application/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/testing/29-real-life-application", + "index": "apps/testing/29-real-life-application/src/index.html", + "main": "apps/testing/29-real-life-application/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/testing/29-real-life-application/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/testing/29-real-life-application/src/favicon.ico", + "apps/testing/29-real-life-application/src/assets" + ], + "styles": [ + "apps/testing/29-real-life-application/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "testing-real-life-application:build:production" + }, + "development": { + "buildTarget": "testing-real-life-application:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "testing-real-life-application:build" + } + }, + "test": { + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}", + "{projectRoot}/coverage" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + }, + "component-test": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/testing/29-real-life-application/cypress.config.ts", + "testingType": "component", + "skipServe": true, + "devServerTarget": "testing-real-life-application:build" + } + } + } +} diff --git a/apps/testing/29-real-life-application/src/app/app.component.ts b/apps/testing/29-real-life-application/src/app/app.component.ts new file mode 100644 index 000000000..a4b00aaec --- /dev/null +++ b/apps/testing/29-real-life-application/src/app/app.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + template: ` + + `, +}) +export class AppComponent {} diff --git a/apps/testing/todos-list/src/app/app.config.ts b/apps/testing/29-real-life-application/src/app/app.config.ts similarity index 100% rename from apps/testing/todos-list/src/app/app.config.ts rename to apps/testing/29-real-life-application/src/app/app.config.ts diff --git a/apps/testing/todos-list/src/app/app.route.ts b/apps/testing/29-real-life-application/src/app/app.route.ts similarity index 100% rename from apps/testing/todos-list/src/app/app.route.ts rename to apps/testing/29-real-life-application/src/app/app.route.ts diff --git a/apps/testing/todos-list/src/app/backend.service.ts b/apps/testing/29-real-life-application/src/app/backend.service.ts similarity index 100% rename from apps/testing/todos-list/src/app/backend.service.ts rename to apps/testing/29-real-life-application/src/app/backend.service.ts diff --git a/apps/testing/29-real-life-application/src/app/detail/detail.component.ts b/apps/testing/29-real-life-application/src/app/detail/detail.component.ts new file mode 100644 index 000000000..0f88f0bf2 --- /dev/null +++ b/apps/testing/29-real-life-application/src/app/detail/detail.component.ts @@ -0,0 +1,56 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { RouterLink } from '@angular/router'; +import { provideComponentStore } from '@ngrx/component-store'; +import { DetailStore } from './detail.store'; + +@Component({ + selector: 'app-detail', + imports: [MatButtonModule, RouterLink, MatProgressBarModule, AsyncPipe], + template: ` +

Ticket Detail:

+ @if (vm$ | async; as vm) { + @if (vm.loading) { + + } + @if (vm.ticket) { +
+
+ Ticket: + {{ vm.ticket.id }} +
+
+ Description: + {{ vm.ticket.description }} +
+
+ AssigneeId: + {{ vm.ticket.assigneeId }} +
+
+ Is done: + {{ vm.ticket.completed }} +
+
+ } + } + + + `, + providers: [provideComponentStore(DetailStore)], + host: { + class: 'p-5 block', + }, +}) +export class DetailComponent { + vm$ = inject(DetailStore).vm$; +} diff --git a/apps/testing/todos-list/src/app/detail/detail.store.ts b/apps/testing/29-real-life-application/src/app/detail/detail.store.ts similarity index 81% rename from apps/testing/todos-list/src/app/detail/detail.store.ts rename to apps/testing/29-real-life-application/src/app/detail/detail.store.ts index 9425b25b2..a5cf12eff 100644 --- a/apps/testing/todos-list/src/app/detail/detail.store.ts +++ b/apps/testing/29-real-life-application/src/app/detail/detail.store.ts @@ -1,11 +1,7 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { - ComponentStore, - OnStateInit, - tapResponse, -} from '@ngrx/component-store'; -import { concatLatestFrom } from '@ngrx/effects'; +import { ComponentStore, OnStateInit } from '@ngrx/component-store'; +import { concatLatestFrom, tapResponse } from '@ngrx/operators'; import { pipe } from 'rxjs'; import { map, mergeMap, tap } from 'rxjs/operators'; import { PARAM_TICKET_ID } from '../app.route'; @@ -27,6 +23,9 @@ export class DetailStore extends ComponentStore implements OnStateInit { + private readonly backend = inject(BackendService); + private readonly route = inject(ActivatedRoute); + readonly ticket$ = this.select((state) => state.ticket); readonly loading$ = this.select((state) => state.loading); readonly error$ = this.select((state) => state.error); @@ -36,10 +35,7 @@ export class DetailStore loading: this.loading$, }); - constructor( - private backend: BackendService, - private route: ActivatedRoute, - ) { + constructor() { super(initialState); } diff --git a/apps/testing/todos-list/src/app/list/list.component.spec.ts b/apps/testing/29-real-life-application/src/app/list/list.component.spec.ts similarity index 100% rename from apps/testing/todos-list/src/app/list/list.component.spec.ts rename to apps/testing/29-real-life-application/src/app/list/list.component.spec.ts diff --git a/apps/testing/29-real-life-application/src/app/list/list.component.ts b/apps/testing/29-real-life-application/src/app/list/list.component.ts new file mode 100644 index 000000000..4c9957139 --- /dev/null +++ b/apps/testing/29-real-life-application/src/app/list/list.component.ts @@ -0,0 +1,71 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { provideComponentStore } from '@ngrx/component-store'; +import { TicketStore } from './ticket.store'; +import { AddComponent } from './ui/add.component'; +import { RowComponent } from './ui/row.component'; + +@Component({ + selector: 'app-list', + imports: [ + ReactiveFormsModule, + AddComponent, + RowComponent, + MatFormFieldModule, + MatProgressBarModule, + MatInputModule, + AsyncPipe, + ], + template: ` +

Tickets

+ + + Search + + + + @if (vm$ | async; as vm) { + + + @if (vm.loading) { + + } +
    + @for (ticket of vm.tickets; track ticket.id) { + + } +
+
+ {{ vm.error }} +
+ } + `, + providers: [provideComponentStore(TicketStore)], + host: { + class: 'p-5 block', + }, +}) +export class ListComponent implements OnInit { + ticketStore = inject(TicketStore); + readonly vm$ = this.ticketStore.vm$; + + search = new FormControl(); + + ngOnInit(): void { + this.ticketStore.search(this.search.valueChanges); + } +} diff --git a/apps/testing/todos-list/src/app/list/ticket.store.spec.ts b/apps/testing/29-real-life-application/src/app/list/ticket.store.spec.ts similarity index 100% rename from apps/testing/todos-list/src/app/list/ticket.store.spec.ts rename to apps/testing/29-real-life-application/src/app/list/ticket.store.spec.ts diff --git a/apps/testing/todos-list/src/app/list/ticket.store.ts b/apps/testing/29-real-life-application/src/app/list/ticket.store.ts similarity index 98% rename from apps/testing/todos-list/src/app/list/ticket.store.ts rename to apps/testing/29-real-life-application/src/app/list/ticket.store.ts index f8bf979a9..838b6038d 100644 --- a/apps/testing/todos-list/src/app/list/ticket.store.ts +++ b/apps/testing/29-real-life-application/src/app/list/ticket.store.ts @@ -3,8 +3,8 @@ import { ComponentStore, OnStateInit, OnStoreInit, - tapResponse, } from '@ngrx/component-store'; +import { tapResponse } from '@ngrx/operators'; import { pipe } from 'rxjs'; import { mergeMap, tap } from 'rxjs/operators'; import { BackendService, Ticket, User } from '../backend.service'; diff --git a/apps/testing/todos-list/src/app/list/ui/add.component.ts b/apps/testing/29-real-life-application/src/app/list/ui/add.component.ts similarity index 76% rename from apps/testing/todos-list/src/app/list/ui/add.component.ts rename to apps/testing/29-real-life-application/src/app/list/ui/add.component.ts index b3e517125..c66fb6d01 100644 --- a/apps/testing/todos-list/src/app/list/ui/add.component.ts +++ b/apps/testing/29-real-life-application/src/app/list/ui/add.component.ts @@ -1,5 +1,4 @@ -import { NgIf } from '@angular/common'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, input, output } from '@angular/core'; import { FormControl, FormGroup, @@ -12,13 +11,11 @@ import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'app-add', - standalone: true, imports: [ ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, - NgIf, ], template: `
@@ -29,10 +26,12 @@ import { MatInputModule } from '@angular/material/input'; matInput formControlName="description" placeholder="My new task" /> - - Description is - required - + @if (form.controls.description.hasError('required')) { + + Description is + required + + } +
+ + + Assign to + + @for (user of users(); track user.id) { + + {{ user.name }} + + } + + + + + +
+ + `, + host: { + class: 'p-4 border border-blue-500 rounded flex', + }, +}) +export class RowComponent { + ticket = input.required(); + users = input.required(); + + assign = output<{ userId: number; ticketId: number }>(); + closeTicket = output(); + + form = new FormGroup({ + assignee: new FormControl(0, { nonNullable: true }), + }); + + submit() { + this.assign.emit({ + ticketId: this.ticket().id, + userId: this.form.getRawValue().assignee, + }); + } +} diff --git a/NX b/apps/testing/29-real-life-application/src/assets/.gitkeep similarity index 100% rename from NX rename to apps/testing/29-real-life-application/src/assets/.gitkeep diff --git a/apps/testing/29-real-life-application/src/favicon.ico b/apps/testing/29-real-life-application/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/testing/29-real-life-application/src/favicon.ico differ diff --git a/apps/testing/29-real-life-application/src/index.html b/apps/testing/29-real-life-application/src/index.html new file mode 100644 index 000000000..91b0bf44a --- /dev/null +++ b/apps/testing/29-real-life-application/src/index.html @@ -0,0 +1,13 @@ + + + + + testing-real-life-application + + + + + + + + diff --git a/apps/testing/29-real-life-application/src/main.ts b/apps/testing/29-real-life-application/src/main.ts new file mode 100644 index 000000000..4fcb1ec76 --- /dev/null +++ b/apps/testing/29-real-life-application/src/main.ts @@ -0,0 +1,10 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; + +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/testing/todos-list/src/styles.scss b/apps/testing/29-real-life-application/src/styles.scss similarity index 100% rename from apps/testing/todos-list/src/styles.scss rename to apps/testing/29-real-life-application/src/styles.scss diff --git a/apps/testing/29-real-life-application/src/test-setup.ts b/apps/testing/29-real-life-application/src/test-setup.ts new file mode 100644 index 000000000..9d9196920 --- /dev/null +++ b/apps/testing/29-real-life-application/src/test-setup.ts @@ -0,0 +1,4 @@ +import '@testing-library/jest-dom'; +import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; + +setupZoneTestEnv(); diff --git a/apps/testing/29-real-life-application/tailwind.config.js b/apps/testing/29-real-life-application/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/testing/29-real-life-application/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/testing/29-real-life-application/tsconfig.app.json b/apps/testing/29-real-life-application/tsconfig.app.json new file mode 100644 index 000000000..5fdad8685 --- /dev/null +++ b/apps/testing/29-real-life-application/tsconfig.app.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "cypress/**/*", + "cypress.config.ts", + "**/*.cy.ts", + "**/*.cy.js", + "**/*.cy.tsx", + "**/*.cy.jsx" + ] +} diff --git a/apps/testing/table/tsconfig.editor.json b/apps/testing/29-real-life-application/tsconfig.editor.json similarity index 100% rename from apps/testing/table/tsconfig.editor.json rename to apps/testing/29-real-life-application/tsconfig.editor.json diff --git a/apps/testing/29-real-life-application/tsconfig.json b/apps/testing/29-real-life-application/tsconfig.json new file mode 100644 index 000000000..397e59bc8 --- /dev/null +++ b/apps/testing/29-real-life-application/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./cypress/tsconfig .json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/testing/29-real-life-application/tsconfig.spec.json b/apps/testing/29-real-life-application/tsconfig.spec.json new file mode 100644 index 000000000..1cb322824 --- /dev/null +++ b/apps/testing/29-real-life-application/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "preserve", + "types": ["jest", "node", "@testing-library/jest-dom"], + "moduleResolution": "bundler", + "isolatedModules": true + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/testing/checkbox/jest.config.ts b/apps/testing/checkbox/jest.config.ts deleted file mode 100644 index 0c5902908..000000000 --- a/apps/testing/checkbox/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-checkbox', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - coverageDirectory: '../../../coverage/apps/testing/checkbox', - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/checkbox/project.json b/apps/testing/checkbox/project.json deleted file mode 100644 index 7a7ae0f1b..000000000 --- a/apps/testing/checkbox/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "testing-checkbox", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/testing/checkbox/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/checkbox", - "index": "apps/testing/checkbox/src/index.html", - "main": "apps/testing/checkbox/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/checkbox/tsconfig.app.json", - "assets": [ - "apps/testing/checkbox/src/favicon.ico", - "apps/testing/checkbox/src/assets" - ], - "styles": ["apps/testing/checkbox/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-checkbox:build:production" - }, - "development": { - "buildTarget": "testing-checkbox:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-checkbox:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/checkbox/jest.config.ts" - } - } - } -} diff --git a/apps/testing/checkbox/src/app/app.component.ts b/apps/testing/checkbox/src/app/app.component.ts deleted file mode 100644 index 936cc781e..000000000 --- a/apps/testing/checkbox/src/app/app.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - standalone: true, - selector: 'app-root', - template: ` - - - - `, -}) -export class AppComponent { - check = false; - - toggleCheck() { - this.check = !this.check; - } -} diff --git a/apps/testing/checkbox/src/main.ts b/apps/testing/checkbox/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/testing/checkbox/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/testing/checkbox/src/test-setup.ts b/apps/testing/checkbox/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/checkbox/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/checkbox/tsconfig.app.json b/apps/testing/checkbox/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/testing/checkbox/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/testing/checkbox/tsconfig.json b/apps/testing/checkbox/tsconfig.json deleted file mode 100644 index e85865cf5..000000000 --- a/apps/testing/checkbox/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/checkbox/tsconfig.spec.json b/apps/testing/checkbox/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/checkbox/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/create-harness/README.md b/apps/testing/create-harness/README.md deleted file mode 100644 index 600f34055..000000000 --- a/apps/testing/create-harness/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Harness Creation - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve testing-create-harness -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/24-harness-creation/). diff --git a/apps/testing/create-harness/jest.config.ts b/apps/testing/create-harness/jest.config.ts deleted file mode 100644 index 1178b8aaf..000000000 --- a/apps/testing/create-harness/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-create-harness', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/create-harness/project.json b/apps/testing/create-harness/project.json deleted file mode 100644 index 800c4d577..000000000 --- a/apps/testing/create-harness/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "testing-create-harness", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/testing/create-harness/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/create-harness", - "index": "apps/testing/create-harness/src/index.html", - "main": "apps/testing/create-harness/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/create-harness/tsconfig.app.json", - "assets": [ - "apps/testing/create-harness/src/favicon.ico", - "apps/testing/create-harness/src/assets" - ], - "styles": ["apps/testing/create-harness/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-create-harness:build:production" - }, - "development": { - "buildTarget": "testing-create-harness:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-create-harness:build" - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/create-harness/jest.config.ts" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/testing/create-harness/src/app/app.component.ts b/apps/testing/create-harness/src/app/app.component.ts deleted file mode 100644 index 06c7eb9af..000000000 --- a/apps/testing/create-harness/src/app/app.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Component, signal } from '@angular/core'; -import { SliderComponent } from './slider.component'; - -@Component({ - standalone: true, - imports: [SliderComponent], - selector: 'app-root', - template: ` -

Slider 1: {{ slider1Value() }}

- -

Slider 2: {{ slider2Value() }}

-

Enabled only if Slider 1 > 20

- - `, - styles: [''], -}) -export class AppComponent { - slider1Value = signal(10); - slider2Value = signal(0); -} diff --git a/apps/testing/create-harness/src/app/slider.component.ts b/apps/testing/create-harness/src/app/slider.component.ts deleted file mode 100644 index bc77ff1f3..000000000 --- a/apps/testing/create-harness/src/app/slider.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Component, Input, OnInit, Output, signal } from '@angular/core'; -import { toObservable } from '@angular/core/rxjs-interop'; -import { FormsModule } from '@angular/forms'; -import { MatCardModule } from '@angular/material/card'; -import { MatIconModule } from '@angular/material/icon'; -import { MatSliderModule } from '@angular/material/slider'; -import { skip } from 'rxjs'; - -@Component({ - selector: 'app-slider', - template: ` - - -
- - {{ minValue }} - - - - {{ maxValue }} - -
-
-
- `, - styles: [ - ` - .mat-mdc-slider { - max-width: 300px; - width: 100%; - } - - .mat-mdc-card { - margin-top: 8px; - flex-direction: row; - } - `, - ], - standalone: true, - imports: [MatCardModule, MatSliderModule, MatIconModule, FormsModule], -}) -export class SliderComponent implements OnInit { - @Input() step = 1; - @Input() minValue = 0; - @Input() maxValue = 100; - @Input() disabled = false; - - value = signal(0); - @Output() valueChange = toObservable(this.value).pipe(skip(1)); - - ngOnInit(): void { - this.value.set(this.minValue); - } - - back() { - if (this.value() - this.step >= this.minValue) { - this.value.update((v) => v - this.step); - } - } - - forward() { - if (this.value() + this.step <= this.maxValue) { - this.value.update((v) => v + this.step); - } - } -} diff --git a/apps/testing/create-harness/src/index.html b/apps/testing/create-harness/src/index.html deleted file mode 100644 index 03bd39e4f..000000000 --- a/apps/testing/create-harness/src/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - create-harness - - - - - - - - - diff --git a/apps/testing/create-harness/src/main.ts b/apps/testing/create-harness/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/testing/create-harness/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/testing/create-harness/src/styles.scss b/apps/testing/create-harness/src/styles.scss deleted file mode 100644 index 94dbf8ff3..000000000 --- a/apps/testing/create-harness/src/styles.scss +++ /dev/null @@ -1,29 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ -@use '@angular/material' as mat; - -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* You can add global styles to this file, and also import other style files */ - -@include mat.core(); - -$theme-primary: mat.define-palette(mat.$indigo-palette); -$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - -$theme-warn: mat.define-palette(mat.$red-palette); - -$theme: mat.define-light-theme( - ( - color: ( - primary: $theme-primary, - accent: $theme-accent, - warn: $theme-warn, - ), - typography: mat.define-typography-config(), - ) -); - -@include mat.dialog-theme($theme); -@include mat.all-component-themes($theme); diff --git a/apps/testing/create-harness/src/test-setup.ts b/apps/testing/create-harness/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/create-harness/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/create-harness/tsconfig.app.json b/apps/testing/create-harness/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/testing/create-harness/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/testing/create-harness/tsconfig.json b/apps/testing/create-harness/tsconfig.json deleted file mode 100644 index 4e4cd748d..000000000 --- a/apps/testing/create-harness/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./tsconfig.spec.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/create-harness/tsconfig.spec.json b/apps/testing/create-harness/tsconfig.spec.json deleted file mode 100644 index 758c12092..000000000 --- a/apps/testing/create-harness/tsconfig.spec.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "target": "es2016", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/harness/jest.config.ts b/apps/testing/harness/jest.config.ts deleted file mode 100644 index 2b9e6d44c..000000000 --- a/apps/testing/harness/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-harness', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/harness/project.json b/apps/testing/harness/project.json deleted file mode 100644 index 6312e83d4..000000000 --- a/apps/testing/harness/project.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "testing-harness", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/testing/harness/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/harness", - "index": "apps/testing/harness/src/index.html", - "main": "apps/testing/harness/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/harness/tsconfig.app.json", - "assets": [ - "apps/testing/harness/src/favicon.ico", - "apps/testing/harness/src/assets" - ], - "styles": ["apps/testing/harness/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-harness:build:production" - }, - "development": { - "buildTarget": "testing-harness:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-harness:build" - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/harness/jest.config.ts" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - } -} diff --git a/apps/testing/harness/src/app/app.component.ts b/apps/testing/harness/src/app/app.component.ts deleted file mode 100644 index 1f89505d8..000000000 --- a/apps/testing/harness/src/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; -import { ChildComponent } from './child.component'; - -@Component({ - standalone: true, - imports: [ChildComponent], - selector: 'app-root', - template: ` - - `, - styles: [''], -}) -export class AppComponent {} diff --git a/apps/testing/harness/src/app/child.component.ts b/apps/testing/harness/src/app/child.component.ts deleted file mode 100644 index cc9a03e74..000000000 --- a/apps/testing/harness/src/app/child.component.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Component } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { MatCardModule } from '@angular/material/card'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; -import { MatSliderModule } from '@angular/material/slider'; - -@Component({ - selector: 'app-child', - template: ` - - -

Slider configuration

- -
- - Value - - - - Min value - - - - Max value - - - - Step size - - -
- -
- Show ticks -
- -
- Show thumb label -
- -
- Disabled -
-
-
- - - -
- - - - - -
-
-
- `, - styles: [ - ` - .mat-mdc-slider { - max-width: 300px; - width: 100%; - } - - .mat-mdc-card + .mat-mdc-card { - margin-top: 8px; - } - `, - ], - standalone: true, - imports: [ - MatCardModule, - MatFormFieldModule, - MatInputModule, - FormsModule, - MatCheckboxModule, - MatSliderModule, - MatIconModule, - ], -}) -export class ChildComponent { - disabled = false; - max = 100; - min = 0; - showTicks = false; - step = 1; - thumbLabel = false; - value = 0; - - back() { - if (this.value - this.step >= this.min) { - this.value -= this.step; - } - } - - forward() { - if (this.value + this.step <= this.max) { - this.value += this.step; - } - } -} diff --git a/apps/testing/harness/src/index.html b/apps/testing/harness/src/index.html deleted file mode 100644 index a4122017e..000000000 --- a/apps/testing/harness/src/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - harness - - - - - - - - - diff --git a/apps/testing/harness/src/main.ts b/apps/testing/harness/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/testing/harness/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/testing/harness/src/styles.scss b/apps/testing/harness/src/styles.scss deleted file mode 100644 index c9c067e5f..000000000 --- a/apps/testing/harness/src/styles.scss +++ /dev/null @@ -1,28 +0,0 @@ -@use '@angular/material' as mat; - -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* You can add global styles to this file, and also import other style files */ - -@include mat.core(); - -$theme-primary: mat.define-palette(mat.$indigo-palette); -$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - -$theme-warn: mat.define-palette(mat.$red-palette); - -$theme: mat.define-light-theme( - ( - color: ( - primary: $theme-primary, - accent: $theme-accent, - warn: $theme-warn, - ), - typography: mat.define-typography-config(), - ) -); - -@include mat.dialog-theme($theme); -@include mat.all-component-themes($theme); diff --git a/apps/testing/harness/src/test-setup.ts b/apps/testing/harness/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/harness/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/harness/tsconfig.app.json b/apps/testing/harness/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/testing/harness/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/testing/harness/tsconfig.json b/apps/testing/harness/tsconfig.json deleted file mode 100644 index 4e4cd748d..000000000 --- a/apps/testing/harness/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./tsconfig.spec.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/harness/tsconfig.spec.json b/apps/testing/harness/tsconfig.spec.json deleted file mode 100644 index 758c12092..000000000 --- a/apps/testing/harness/tsconfig.spec.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "target": "es2016", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/input-output/cypress.config.ts b/apps/testing/input-output/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/input-output/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/input-output/cypress/support/commands.ts b/apps/testing/input-output/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/input-output/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/input-output/jest.config.ts b/apps/testing/input-output/jest.config.ts deleted file mode 100644 index 63370e2a3..000000000 --- a/apps/testing/input-output/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-input-output', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/input-output/project.json b/apps/testing/input-output/project.json deleted file mode 100644 index 4863e5e7b..000000000 --- a/apps/testing/input-output/project.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "testing-input-output", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/input-output/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/input-output", - "index": "apps/testing/input-output/src/index.html", - "main": "apps/testing/input-output/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/input-output/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/input-output/src/favicon.ico", - "apps/testing/input-output/src/assets" - ], - "styles": ["apps/testing/input-output/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-input-output:build:production" - }, - "development": { - "buildTarget": "testing-input-output:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-input-output:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/input-output/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/input-output/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-input-output:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/input-output/src/app/app.component.ts b/apps/testing/input-output/src/app/app.component.ts deleted file mode 100644 index 6a6392a4b..000000000 --- a/apps/testing/input-output/src/app/app.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from '@angular/core'; -import { CounterComponent } from './counter.component'; - -@Component({ - standalone: true, - imports: [CounterComponent], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent { - log(counter: number) { - console.log('output log', counter); - } -} diff --git a/apps/testing/input-output/src/app/counter.component.ts b/apps/testing/input-output/src/app/counter.component.ts deleted file mode 100644 index 1ca95430d..000000000 --- a/apps/testing/input-output/src/app/counter.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { AsyncPipe } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - Output, -} from '@angular/core'; -import { LetDirective } from '@ngrx/component'; -import { ComponentStore } from '@ngrx/component-store'; - -@Component({ - selector: 'app-counter', - standalone: true, - imports: [AsyncPipe, LetDirective], - template: ` - -

Counter: {{ counter }}

- - - -
- `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CounterComponent extends ComponentStore<{ counter: number }> { - @Input() set initialValue(initialValue: number) { - this.patchState({ counter: initialValue }); - } - - @Output() send = new EventEmitter(); - - readonly counter$ = this.select((state) => state.counter); - - readonly increment = this.updater((state) => ({ - counter: state.counter + 1, - })); - readonly decrement = this.updater((state) => ({ - counter: state.counter - 1, - })); - - constructor() { - super({ counter: 0 }); - } -} diff --git a/apps/testing/input-output/src/index.html b/apps/testing/input-output/src/index.html deleted file mode 100644 index bb1c5edf3..000000000 --- a/apps/testing/input-output/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - TestingInputOutput - - - - - - - - diff --git a/apps/testing/input-output/src/main.ts b/apps/testing/input-output/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/testing/input-output/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/testing/input-output/src/test-setup.ts b/apps/testing/input-output/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/input-output/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/input-output/tsconfig.app.json b/apps/testing/input-output/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/input-output/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/input-output/tsconfig.json b/apps/testing/input-output/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/input-output/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/input-output/tsconfig.spec.json b/apps/testing/input-output/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/input-output/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/modal/cypress.config.ts b/apps/testing/modal/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/modal/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/modal/cypress/support/commands.ts b/apps/testing/modal/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/modal/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/modal/jest.config.ts b/apps/testing/modal/jest.config.ts deleted file mode 100644 index 809080bcc..000000000 --- a/apps/testing/modal/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-modal', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/modal/project.json b/apps/testing/modal/project.json deleted file mode 100644 index 55c019c44..000000000 --- a/apps/testing/modal/project.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "name": "testing-modal", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/modal/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/modal", - "index": "apps/testing/modal/src/index.html", - "main": "apps/testing/modal/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/modal/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/modal/src/favicon.ico", - "apps/testing/modal/src/assets" - ], - "styles": [ - "apps/testing/modal/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-modal:build:production" - }, - "development": { - "buildTarget": "testing-modal:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-modal:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/modal/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/modal/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-modal:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/modal/src/app/app.component.ts b/apps/testing/modal/src/app/app.component.ts deleted file mode 100644 index afb4b291f..000000000 --- a/apps/testing/modal/src/app/app.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AsyncPipe } from '@angular/common'; -import { Component, inject } from '@angular/core'; -import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatDialog, MatDialogModule } from '@angular/material/dialog'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { BehaviorSubject } from 'rxjs'; -import { ErrorDialog } from './error.dialog'; -import { ProfilConfirmationDialog } from './profil-confirmation.dialog'; -@Component({ - standalone: true, - imports: [ - ReactiveFormsModule, - MatDialogModule, - MatFormFieldModule, - MatInputModule, - MatButtonModule, - AsyncPipe, - ], - selector: 'app-root', - host: { - class: 'p-4 block flex gap-4 items-center', - }, - template: ` - - Name - - - - -
{{ result$ | async }}
- `, -}) -export class AppComponent { - private modal = inject(MatDialog); - private result = new BehaviorSubject(''); - result$ = this.result.asObservable(); - - name = new FormControl('', { nonNullable: true }); - - confirm() { - if (!this.name.value) { - this.modal.open(ErrorDialog); - return; - } - - this.modal - .open(ProfilConfirmationDialog, { - data: { - name: this.name.value, - }, - }) - .afterClosed() - .subscribe((result) => - this.result.next( - result ? 'Name has been submitted' : 'Name is invalid !!', - ), - ); - } -} diff --git a/apps/testing/modal/src/index.html b/apps/testing/modal/src/index.html deleted file mode 100644 index f63ff6890..000000000 --- a/apps/testing/modal/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - TestingModal - - - - - - - - diff --git a/apps/testing/modal/src/main.ts b/apps/testing/modal/src/main.ts deleted file mode 100644 index 7961924bf..000000000 --- a/apps/testing/modal/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/testing/modal/src/test-setup.ts b/apps/testing/modal/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/modal/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/modal/tsconfig.app.json b/apps/testing/modal/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/modal/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/modal/tsconfig.json b/apps/testing/modal/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/modal/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/modal/tsconfig.spec.json b/apps/testing/modal/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/modal/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/nested/README.md b/apps/testing/nested/README.md deleted file mode 100644 index 8e1876a73..000000000 --- a/apps/testing/nested/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Nested Components - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve testing-nested -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/18-nested-comp/). diff --git a/apps/testing/nested/cypress.config.ts b/apps/testing/nested/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/nested/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/nested/cypress/support/commands.ts b/apps/testing/nested/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/nested/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/nested/jest.config.ts b/apps/testing/nested/jest.config.ts deleted file mode 100644 index a89947bd9..000000000 --- a/apps/testing/nested/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-nested', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/nested/project.json b/apps/testing/nested/project.json deleted file mode 100644 index 2c60724a2..000000000 --- a/apps/testing/nested/project.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "testing-nested", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/nested/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/nested", - "index": "apps/testing/nested/src/index.html", - "main": "apps/testing/nested/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/nested/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/nested/src/favicon.ico", - "apps/testing/nested/src/assets" - ], - "styles": ["apps/testing/nested/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-nested:build:production" - }, - "development": { - "buildTarget": "testing-nested:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-nested:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/nested/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/nested/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-nested:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/nested/src/app/app.component.ts b/apps/testing/nested/src/app/app.component.ts deleted file mode 100644 index 098836b6f..000000000 --- a/apps/testing/nested/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { ChildComponent } from './child.component'; - -@Component({ - standalone: true, - imports: [ChildComponent], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent {} diff --git a/apps/testing/nested/src/app/child.component.ts b/apps/testing/nested/src/app/child.component.ts deleted file mode 100644 index bcee84ecd..000000000 --- a/apps/testing/nested/src/app/child.component.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { NgIf } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - Output, - inject, -} from '@angular/core'; -import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { HttpService } from './http.service'; - -@Component({ - selector: 'app-input', - standalone: true, - imports: [ReactiveFormsModule], - template: ` - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class InputComponent { - title = new FormControl('', { nonNullable: true }); -} - -@Component({ - selector: 'result', - standalone: true, - template: ` -

Title is {{ title }}

- `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ResultComponent { - @Input() title = ''; -} - -@Component({ - selector: 'app-button', - standalone: true, - template: ` - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ButtonComponent { - @Output() validate = new EventEmitter(); -} - -@Component({ - selector: 'app-error', - standalone: true, - template: ` -

Title is required !!!

- `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ErrorComponent { - @Output() validate = new EventEmitter(); -} - -@Component({ - selector: 'app-child', - standalone: true, - imports: [ - ResultComponent, - ButtonComponent, - InputComponent, - ErrorComponent, - NgIf, - ], - template: ` - - - - - `, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ChildComponent { - http = inject(HttpService); - - showError = false; - - submit(title: string) { - this.showError = false; - if (title === '') { - this.showError = true; - return; - } - - this.http.sendTitle(title); - } -} diff --git a/apps/testing/nested/src/index.html b/apps/testing/nested/src/index.html deleted file mode 100644 index 620e0cd2d..000000000 --- a/apps/testing/nested/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - TestingNested - - - - - - - - diff --git a/apps/testing/nested/src/main.ts b/apps/testing/nested/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/testing/nested/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/testing/nested/src/test-setup.ts b/apps/testing/nested/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/nested/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/nested/tsconfig.app.json b/apps/testing/nested/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/nested/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/nested/tsconfig.json b/apps/testing/nested/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/nested/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/nested/tsconfig.spec.json b/apps/testing/nested/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/nested/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/router-outlet/README.md b/apps/testing/router-outlet/README.md deleted file mode 100644 index 774915930..000000000 --- a/apps/testing/router-outlet/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Router - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve testing-router-outlet -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/17-router/). diff --git a/apps/testing/router-outlet/cypress.config.ts b/apps/testing/router-outlet/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/router-outlet/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/router-outlet/cypress/support/commands.ts b/apps/testing/router-outlet/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/router-outlet/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/router-outlet/jest.config.ts b/apps/testing/router-outlet/jest.config.ts deleted file mode 100644 index 0bca8aebb..000000000 --- a/apps/testing/router-outlet/jest.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-router-outlet', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/router-outlet/project.json b/apps/testing/router-outlet/project.json deleted file mode 100644 index 41697e12a..000000000 --- a/apps/testing/router-outlet/project.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "testing-router-outlet", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/router-outlet/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/router-outlet", - "index": "apps/testing/router-outlet/src/index.html", - "main": "apps/testing/router-outlet/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/router-outlet/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/router-outlet/src/favicon.ico", - "apps/testing/router-outlet/src/assets" - ], - "styles": ["apps/testing/router-outlet/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-router-outlet:build:production" - }, - "development": { - "buildTarget": "testing-router-outlet:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-router-outlet:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/router-outlet/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/router-outlet/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-router-outlet:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/router-outlet/src/app/app.component.ts b/apps/testing/router-outlet/src/app/app.component.ts deleted file mode 100644 index 3b420a867..000000000 --- a/apps/testing/router-outlet/src/app/app.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterLink, RouterOutlet } from '@angular/router'; - -@Component({ - standalone: true, - imports: [RouterOutlet, RouterLink], - selector: 'app-root', - styles: [ - ` - h1 { - margin-bottom: 0; - } - nav a { - padding: 1rem; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #e8e8e8; - color: #3d3d3d; - border-radius: 4px; - margin-bottom: 10px; - } - nav a:hover { - color: white; - background-color: #42545c; - } - nav a.active { - background-color: black; - } - `, - ], - template: ` -

Library

- - - - - `, -}) -export class AppComponent {} diff --git a/apps/testing/router-outlet/src/app/shelf.component.ts b/apps/testing/router-outlet/src/app/shelf.component.ts deleted file mode 100644 index a7da5af1a..000000000 --- a/apps/testing/router-outlet/src/app/shelf.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { AsyncPipe, JsonPipe, NgFor } from '@angular/common'; -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { map } from 'rxjs'; -import { availableBooks } from './book.model'; - -@Component({ - selector: 'app-shelf', - standalone: true, - imports: [AsyncPipe, JsonPipe, NgFor], - template: ` -
    -
  • - Borrowed Book: {{ book.name }} by {{ book.author }} -
  • -
- `, - styles: [], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export default class ShelfComponent { - readonly books = inject(ActivatedRoute).queryParams.pipe( - map((params) => params?.['book'].toLowerCase()), - map((param) => - availableBooks.filter( - (b) => - b.name.toLowerCase().includes(param) || - b.author.toLowerCase().includes(param), - ), - ), - ); -} diff --git a/apps/testing/router-outlet/src/index.html b/apps/testing/router-outlet/src/index.html deleted file mode 100644 index b7065804e..000000000 --- a/apps/testing/router-outlet/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - RouterTesting - - - - - - - - diff --git a/apps/testing/router-outlet/src/main.ts b/apps/testing/router-outlet/src/main.ts deleted file mode 100644 index 7961924bf..000000000 --- a/apps/testing/router-outlet/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/testing/router-outlet/src/styles.scss b/apps/testing/router-outlet/src/styles.scss deleted file mode 100644 index 90d4ee007..000000000 --- a/apps/testing/router-outlet/src/styles.scss +++ /dev/null @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/apps/testing/router-outlet/src/test-setup.ts b/apps/testing/router-outlet/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/router-outlet/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/router-outlet/tsconfig.app.json b/apps/testing/router-outlet/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/router-outlet/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/router-outlet/tsconfig.json b/apps/testing/router-outlet/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/router-outlet/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/router-outlet/tsconfig.spec.json b/apps/testing/router-outlet/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/router-outlet/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/table/README.md b/apps/testing/table/README.md deleted file mode 100644 index ff3b4b560..000000000 --- a/apps/testing/table/README.md +++ /dev/null @@ -1,38 +0,0 @@ -

Table testing

- -> author: thomas-laforge - -## Statement: - -NOT IMPLEMENTED YET - - - -### Submitting your work - -1. Fork the project -2. clone it -3. npm ci -4. `npx nx serve testing-table` to play with the application -5. `npx nx test testing-table` to test your application with Testing Library -6. `npx nx component-test testing-table --watch` to test your application with Cypress -7. _...work on it_ -8. Commit your work -9. Submit a PR with a title beginning with **Answer:22** that I will review and other dev can review. - -nested testing -nested testing solution author - - - -_You can ask any question on_ twitter diff --git a/apps/testing/table/cypress.config.ts b/apps/testing/table/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/table/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/table/cypress/support/commands.ts b/apps/testing/table/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/table/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/table/cypress/support/component-index.html b/apps/testing/table/cypress/support/component-index.html deleted file mode 100644 index c0a4681dc..000000000 --- a/apps/testing/table/cypress/support/component-index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - testing-table Components App - - -
- - diff --git a/apps/testing/table/jest.config.ts b/apps/testing/table/jest.config.ts deleted file mode 100644 index 56b0e7df7..000000000 --- a/apps/testing/table/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-table', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/table/project.json b/apps/testing/table/project.json deleted file mode 100644 index db95cb4ea..000000000 --- a/apps/testing/table/project.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "name": "testing-table", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/table/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/table", - "index": "apps/testing/table/src/index.html", - "main": "apps/testing/table/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/table/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/table/src/favicon.ico", - "apps/testing/table/src/assets" - ], - "styles": ["apps/testing/table/src/styles.scss"], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-table:build:production" - }, - "development": { - "buildTarget": "testing-table:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-table:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/table/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/table/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-table:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/table/src/app/app.component.ts b/apps/testing/table/src/app/app.component.ts deleted file mode 100644 index 236bc50a6..000000000 --- a/apps/testing/table/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { TableComponent } from './table.component'; - -@Component({ - standalone: true, - imports: [TableComponent], - selector: 'app-root', - template: ` - - `, -}) -export class AppComponent {} diff --git a/apps/testing/table/src/app/table.component.spec.ts b/apps/testing/table/src/app/table.component.spec.ts deleted file mode 100644 index db4015d9f..000000000 --- a/apps/testing/table/src/app/table.component.spec.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { MatTableHarness } from '@angular/material/table/testing'; -import { render } from '@testing-library/angular'; -import userEvent from '@testing-library/user-event'; -import { TableComponent } from './table.component'; - -describe('AppComponent', () => { - // let loader: HarnessLoader; - // let fixture: ComponentFixture; - // let loader: HarnessLoader; - - // beforeEach(async () => { - // const view = await render(TableComponent); - // fixture = view.fixture; - // loader = TestbedHarnessEnvironment.loader(fixture); - // }); - it('error modal is displayed if you click on "Confirm" without inputing a name', async () => { - userEvent.setup(); - const { fixture } = await render(TableComponent); - const loader = TestbedHarnessEnvironment.loader(fixture); - - const tables = await loader.getAllHarnesses(MatTableHarness); - expect(tables.length).toBe(1); - - // const confirmButton = await screen.findByRole('button', { - // name: /confirm/i, - // }); - // await userEvent.click(confirmButton); - - // const dialogControl = await screen.findByRole('dialog'); - // expect(dialogControl).toBeInTheDocument(); - // const errorTitle = await screen.findByRole('heading', { - // name: /error/i, - // }); - // expect(errorTitle).toBeInTheDocument(); - - // const okButton = await screen.findByRole('button', { - // name: /ok/i, - // }); - // await userEvent.click(okButton); - }); - - // subscription('error message is shown if you click "Cancel" in the confirmation modal after submitting a name', async () => { - // userEvent.setup(); - // await render(AppComponent); - - // const inputControl = await screen.getByRole('textbox'); - // await userEvent.type(inputControl, 'toto'); - - // const confirmButton = await screen.findByRole('button', { - // name: /confirm/i, - // }); - // await userEvent.click(confirmButton); - - // const dialogControl = await screen.findByRole('dialog'); - // expect(dialogControl).toBeInTheDocument(); - // const profilTitle = await screen.findByRole('heading', { - // name: /profil/i, - // }); - // expect(profilTitle).toBeInTheDocument(); - - // const cancelButton = await screen.findByRole('button', { - // name: /cancel/i, - // }); - // await userEvent.click(cancelButton); - - // const errorText = await screen.getByText('Name is invalid !!'); - // expect(errorText).toBeInTheDocument(); - // }); - - // subscription('confirm message is shown if you click "Confirm" in the confirmation modal after submitting a name', async () => { - // userEvent.setup(); - // await render(AppComponent); - - // const inputControl = await screen.getByRole('textbox'); - // await userEvent.type(inputControl, 'toto'); - - // const confirmButton = await screen.findByRole('button', { - // name: /confirm/i, - // }); - // await userEvent.click(confirmButton); - - // const dialogControl = await screen.findByRole('dialog'); - // expect(dialogControl).toBeInTheDocument(); - // const profilTitle = await screen.findByRole('heading', { - // name: /profil/i, - // }); - // expect(profilTitle).toBeInTheDocument(); - - // const confirmDialogButton = await screen.findByRole('button', { - // name: /confirm/i, - // }); - // await userEvent.click(confirmDialogButton); - - // const confirmText = await screen.getByText('Name has been submitted'); - // expect(confirmText).toBeInTheDocument(); - // }); -}); diff --git a/apps/testing/table/src/app/table.component.ts b/apps/testing/table/src/app/table.component.ts deleted file mode 100644 index 74df216e6..000000000 --- a/apps/testing/table/src/app/table.component.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { FakeBackendService } from '@angular-challenges/testing-table/backend'; -import { AsyncPipe, DatePipe, NgIf } from '@angular/common'; -import { AfterViewInit, Component, ViewChild, inject } from '@angular/core'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatSort, MatSortModule, SortDirection } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -import { User } from '@ngneat/falso'; -import { LetDirective } from '@ngrx/component'; -import { ComponentStore, tapResponse } from '@ngrx/component-store'; -import { map, pipe, startWith, switchMap, tap } from 'rxjs'; - -interface TableState { - loading: boolean; - error?: string; - users: User[]; -} - -@Component({ - selector: 'app-table', - standalone: true, - imports: [ - MatFormFieldModule, - MatInputModule, - MatTableModule, - MatSortModule, - MatPaginatorModule, - MatProgressSpinnerModule, - LetDirective, - NgIf, - AsyncPipe, - DatePipe, - ], - template: ` -
-
- - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
FirstName{{ row.firstName }}LastName{{ row.lastName }}Email{{ row.email }}
-
- - -
- `, -}) -export class TableComponent - extends ComponentStore - implements AfterViewInit -{ - readonly displayedColumns = ['firstName', 'lastName', 'email']; - - private api = inject(FakeBackendService); - - readonly issues$ = this.select((s) => s.users).pipe( - tap((t) => console.log('UserNEw ', t)), - ); - readonly loading$ = this.select((s) => s.loading); - readonly error$ = this.select((s) => s.error); - readonly resultsLength$ = this.select((s) => 100); - - // resultsLength = 0; - // isLoadingResults = true; - // isRateLimitReached = false; - - @ViewChild(MatPaginator) paginator!: MatPaginator; - @ViewChild(MatSort) sort!: MatSort; - - constructor() { - super({ loading: false, users: [] }); - } - - readonly loadData = this.effect<{ - sortActive: keyof User; - sortDir: SortDirection; - pageIndex: number; - }>( - pipe( - tap((t) => console.log('cocou', t)), - tap(() => this.patchState({ loading: true, users: [] })), - switchMap(({ sortActive, sortDir, pageIndex }) => - this.api.getUsers(sortActive, sortDir, pageIndex).pipe( - tap((t) => console.log('user', t)), - tapResponse( - (data) => this.patchState({ users: data, loading: false }), - (err) => this.patchState({ error: err as string, loading: false }), - ), - ), - ), - ), - ); - - ngAfterViewInit(): void { - // due to ExpressionChangedAfterItHasBeenCheckedError - console.log('cocuo', this.sort, this.paginator); - this.loadData( - this.select({ - sortActive: this.sort.sortChange.pipe( - map((s) => s.active as keyof User), - ), - sortDir: this.sort.sortChange.pipe(map((s) => s.direction)), - pageIndex: this.paginator.page.pipe(map((p) => p.pageIndex)), - }).pipe( - startWith({ - sortActive: this.sort.active as keyof User, - sortDir: this.sort.direction, - pageIndex: 1, - }), - ), - ); - } - - // applyFilter(event: Event) { - // const filterValue = (event.target as HTMLInputElement).value; - // this.dataSource.filter = filterValue.trim().toLowerCase(); - - // if (this.dataSource.paginator) { - // this.dataSource.paginator.firstPage(); - // } - // } -} diff --git a/apps/testing/table/src/index.html b/apps/testing/table/src/index.html deleted file mode 100644 index 11da4b083..000000000 --- a/apps/testing/table/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - TestingTable - - - - - - - - diff --git a/apps/testing/table/src/main.ts b/apps/testing/table/src/main.ts deleted file mode 100644 index b0ca80b94..000000000 --- a/apps/testing/table/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { provideHttpClient } from '@angular/common/http'; -import { bootstrapApplication } from '@angular/platform-browser'; -import { provideAnimations } from '@angular/platform-browser/animations'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, { - providers: [provideAnimations(), provideHttpClient()], -}).catch((err) => console.error(err)); diff --git a/apps/testing/table/src/styles.scss b/apps/testing/table/src/styles.scss deleted file mode 100644 index ce5105b51..000000000 --- a/apps/testing/table/src/styles.scss +++ /dev/null @@ -1,31 +0,0 @@ -@use '@angular/material' as mat; - -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* You can add global styles to this file, and also import other style files */ - -@include mat.core(); - -$theme-primary: mat.define-palette(mat.$indigo-palette); -$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - -$theme-warn: mat.define-palette(mat.$red-palette); - -$theme: mat.define-light-theme( - ( - color: ( - primary: $theme-primary, - accent: $theme-accent, - warn: $theme-warn, - ), - typography: mat.define-typography-config(), - ) -); - -@include mat.core-theme($theme); -@include mat.all-component-themes($theme); -// @include mat.form-field-theme($theme); -// @include mat.input-theme($theme); -// @include mat.paginator-theme($theme); diff --git a/apps/testing/table/src/test-setup.ts b/apps/testing/table/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/table/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/table/tsconfig.app.json b/apps/testing/table/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/table/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/table/tsconfig.json b/apps/testing/table/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/table/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/table/tsconfig.spec.json b/apps/testing/table/tsconfig.spec.json deleted file mode 100644 index a578b4624..000000000 --- a/apps/testing/table/tsconfig.spec.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"], - "target": "ES2016" - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/todos-list/README.md b/apps/testing/todos-list/README.md deleted file mode 100644 index 37a8e93be..000000000 --- a/apps/testing/todos-list/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Real-life Application - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve testing-todos-list -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/testing/29-real-application/). diff --git a/apps/testing/todos-list/cypress.config.ts b/apps/testing/todos-list/cypress.config.ts deleted file mode 100644 index 1abef9c0c..000000000 --- a/apps/testing/todos-list/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; -import { defineConfig } from 'cypress'; - -export default defineConfig({ - component: nxComponentTestingPreset(__filename), -}); diff --git a/apps/testing/todos-list/cypress/fixtures/example.json b/apps/testing/todos-list/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/apps/testing/todos-list/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/apps/testing/todos-list/cypress/support/commands.ts b/apps/testing/todos-list/cypress/support/commands.ts deleted file mode 100644 index e6c897603..000000000 --- a/apps/testing/todos-list/cypress/support/commands.ts +++ /dev/null @@ -1,42 +0,0 @@ -/// -import { mount } from 'cypress/angular'; - -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - mount: typeof mount; - } - } -} - -Cypress.Commands.add('mount', mount); - -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/testing/todos-list/cypress/support/component-index.html b/apps/testing/todos-list/cypress/support/component-index.html deleted file mode 100644 index 57c8a3df4..000000000 --- a/apps/testing/todos-list/cypress/support/component-index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - testing-todos-list Components App - - -
- - diff --git a/apps/testing/todos-list/cypress/support/component.ts b/apps/testing/todos-list/cypress/support/component.ts deleted file mode 100644 index e7c3e3cbc..000000000 --- a/apps/testing/todos-list/cypress/support/component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/component.ts is processed and -// loaded automatically before your subscription files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.ts using ES2015 syntax: -import './commands'; diff --git a/apps/testing/todos-list/cypress/tsconfig.json b/apps/testing/todos-list/cypress/tsconfig.json deleted file mode 100644 index 918d96378..000000000 --- a/apps/testing/todos-list/cypress/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["cypress", "node"], - "sourceMap": false - }, - "include": [ - "support/**/*.ts", - "../cypress.config.ts", - "../**/*.cy.ts", - "../**/*.cy.tsx", - "../**/*.cy.js", - "../**/*.cy.jsx", - "../**/*.d.ts" - ] -} diff --git a/apps/testing/todos-list/jest.config.ts b/apps/testing/todos-list/jest.config.ts deleted file mode 100644 index eb61074e5..000000000 --- a/apps/testing/todos-list/jest.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'testing-todos-list', - preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], - transform: { - '^.+\\.(ts|mjs|js|html)$': [ - 'jest-preset-angular', - { - tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, - ], - }, - transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], - snapshotSerializers: [ - 'jest-preset-angular/build/serializers/no-ng-attributes', - 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; diff --git a/apps/testing/todos-list/project.json b/apps/testing/todos-list/project.json deleted file mode 100644 index b20c00d76..000000000 --- a/apps/testing/todos-list/project.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "name": "testing-todos-list", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/testing/todos-list/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/testing/todos-list", - "index": "apps/testing/todos-list/src/index.html", - "main": "apps/testing/todos-list/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/testing/todos-list/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/testing/todos-list/src/favicon.ico", - "apps/testing/todos-list/src/assets" - ], - "styles": [ - "apps/testing/todos-list/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "testing-todos-list:build:production" - }, - "development": { - "buildTarget": "testing-todos-list:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "testing-todos-list:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/testing/todos-list/jest.config.ts" - } - }, - "component-test": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/testing/todos-list/cypress.config.ts", - "testingType": "component", - "skipServe": true, - "devServerTarget": "testing-todos-list:build" - } - } - }, - "tags": [] -} diff --git a/apps/testing/todos-list/src/app/app.component.ts b/apps/testing/todos-list/src/app/app.component.ts deleted file mode 100644 index 6b61097d4..000000000 --- a/apps/testing/todos-list/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - selector: 'app-root', - standalone: true, - imports: [RouterOutlet], - template: ` - - `, -}) -export class AppComponent {} diff --git a/apps/testing/todos-list/src/app/detail/detail.component.ts b/apps/testing/todos-list/src/app/detail/detail.component.ts deleted file mode 100644 index 7e5eed829..000000000 --- a/apps/testing/todos-list/src/app/detail/detail.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { AsyncPipe, NgIf } from '@angular/common'; -import { Component, inject } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { RouterLink } from '@angular/router'; -import { LetDirective } from '@ngrx/component'; -import { provideComponentStore } from '@ngrx/component-store'; -import { DetailStore } from './detail.store'; - -@Component({ - selector: 'app-detail', - standalone: true, - imports: [ - MatButtonModule, - RouterLink, - NgIf, - AsyncPipe, - MatProgressBarModule, - LetDirective, - ], - template: ` -

Ticket Detail:

- - -
-
- Ticket: - {{ ticket.id }} -
-
- Description: - {{ ticket.description }} -
-
- AssigneeId: - {{ ticket.assigneeId }} -
-
- Is done: - {{ ticket.completed }} -
-
-
- - - `, - providers: [provideComponentStore(DetailStore)], - host: { - class: 'p-5 block', - }, -}) -export class DetailComponent { - vm$ = inject(DetailStore).vm$; -} diff --git a/apps/testing/todos-list/src/app/list/list.component.ts b/apps/testing/todos-list/src/app/list/list.component.ts deleted file mode 100644 index 8942f7cc6..000000000 --- a/apps/testing/todos-list/src/app/list/list.component.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { Component, OnInit, inject } from '@angular/core'; -import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { LetDirective } from '@ngrx/component'; -import { provideComponentStore } from '@ngrx/component-store'; -import { TicketStore } from './ticket.store'; -import { AddComponent } from './ui/add.component'; -import { RowComponent } from './ui/row.component'; - -@Component({ - selector: 'app-list', - standalone: true, - imports: [ - ReactiveFormsModule, - AddComponent, - RowComponent, - MatFormFieldModule, - MatProgressBarModule, - NgIf, - NgFor, - MatInputModule, - LetDirective, - ], - template: ` -

Tickets

- - - Search - - - - - - - -
    - -
-
- {{ vm.error }} -
-
- `, - providers: [provideComponentStore(TicketStore)], - host: { - class: 'p-5 block', - }, -}) -export class ListComponent implements OnInit { - ticketStore = inject(TicketStore); - readonly vm$ = this.ticketStore.vm$; - - search = new FormControl(); - - ngOnInit(): void { - this.ticketStore.search(this.search.valueChanges); - } -} diff --git a/apps/testing/todos-list/src/app/list/ui/row.component.ts b/apps/testing/todos-list/src/app/list/ui/row.component.ts deleted file mode 100644 index ca97d0d65..000000000 --- a/apps/testing/todos-list/src/app/list/ui/row.component.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { NgFor } from '@angular/common'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSelectModule } from '@angular/material/select'; -import { RouterLink } from '@angular/router'; -import { Ticket, TicketUser, User } from '../../backend.service'; - -@Component({ - selector: 'app-row', - standalone: true, - imports: [ - RouterLink, - ReactiveFormsModule, - MatFormFieldModule, - MatInputModule, - MatButtonModule, - MatSelectModule, - NgFor, - ], - template: ` -
  • - -
    -
    - - Assign to - - - {{ user.name }} - - - - -
    - -
    -
  • - `, - host: { - class: 'p-4 border border-blue-500 rounded flex', - }, -}) -export class RowComponent { - @Input() ticket!: TicketUser | Ticket; - @Input() users!: User[]; - - @Output() assign = new EventEmitter<{ userId: number; ticketId: number }>(); - @Output() closeTicket = new EventEmitter(); - - form = new FormGroup({ - assignee: new FormControl(0, { nonNullable: true }), - }); - - submit() { - this.assign.emit({ - ticketId: this.ticket.id, - userId: this.form.getRawValue().assignee, - }); - } -} diff --git a/apps/testing/todos-list/src/index.html b/apps/testing/todos-list/src/index.html deleted file mode 100644 index 8321d8a0e..000000000 --- a/apps/testing/todos-list/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - TestingTodosList - - - - - - - - diff --git a/apps/testing/todos-list/src/main.ts b/apps/testing/todos-list/src/main.ts deleted file mode 100644 index 7961924bf..000000000 --- a/apps/testing/todos-list/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; - -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/testing/todos-list/src/test-setup.ts b/apps/testing/todos-list/src/test-setup.ts deleted file mode 100644 index 15de72a3c..000000000 --- a/apps/testing/todos-list/src/test-setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '@testing-library/jest-dom'; -import 'jest-preset-angular/setup-jest'; diff --git a/apps/testing/todos-list/tsconfig.app.json b/apps/testing/todos-list/tsconfig.app.json deleted file mode 100644 index 01a02ed77..000000000 --- a/apps/testing/todos-list/tsconfig.app.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "cypress/**/*", - "cypress.config.ts", - "**/*.cy.ts", - "**/*.cy.js", - "**/*.cy.tsx", - "**/*.cy.jsx" - ] -} diff --git a/apps/testing/todos-list/tsconfig.editor.json b/apps/testing/todos-list/tsconfig.editor.json deleted file mode 100644 index 8ae117d96..000000000 --- a/apps/testing/todos-list/tsconfig.editor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "compilerOptions": { - "types": ["jest", "node"] - } -} diff --git a/apps/testing/todos-list/tsconfig.json b/apps/testing/todos-list/tsconfig.json deleted file mode 100644 index 3879b94cd..000000000 --- a/apps/testing/todos-list/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - }, - { - "path": "./cypress/tsconfig.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/apps/testing/todos-list/tsconfig.spec.json b/apps/testing/todos-list/tsconfig.spec.json deleted file mode 100644 index c0c092e1e..000000000 --- a/apps/testing/todos-list/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node", "@testing-library/jest-dom"] - }, - "files": ["src/test-setup.ts"], - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/apps/testing/todos-list/.eslintrc.json b/apps/typescript/15-function-overload/.eslintrc.json similarity index 100% rename from apps/testing/todos-list/.eslintrc.json rename to apps/typescript/15-function-overload/.eslintrc.json diff --git a/apps/typescript/15-function-overload/README.md b/apps/typescript/15-function-overload/README.md new file mode 100644 index 000000000..96ce65e9d --- /dev/null +++ b/apps/typescript/15-function-overload/README.md @@ -0,0 +1,13 @@ +# Function Overload + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve typescript-function-overload` +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/typescript/15-typescript-function-overload-fn/). diff --git a/apps/typescript/15-function-overload/project.json b/apps/typescript/15-function-overload/project.json new file mode 100644 index 000000000..b36257d9d --- /dev/null +++ b/apps/typescript/15-function-overload/project.json @@ -0,0 +1,73 @@ +{ + "name": "typescript-function-overload", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/typescript/15-function-overload/src", + "prefix": "app", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/typescript/15-function-overload", + "index": "apps/typescript/15-function-overload/src/index.html", + "main": "apps/typescript/15-function-overload/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/typescript/15-function-overload/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/typescript/15-function-overload/src/favicon.ico", + "apps/typescript/15-function-overload/src/assets" + ], + "styles": ["apps/typescript/15-function-overload/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "typescript-function-overload:build:production" + }, + "development": { + "buildTarget": "typescript-function-overload:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "typescript-function-overload:build" + } + } + } +} diff --git a/apps/typescript/15-function-overload/src/app/app.component.ts b/apps/typescript/15-function-overload/src/app/app.component.ts new file mode 100644 index 000000000..1f06369c1 --- /dev/null +++ b/apps/typescript/15-function-overload/src/app/app.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { createVehicle } from './vehicle.utils'; + +@Component({ + selector: 'app-root', + template: ``, +}) +export class AppComponent { + car = createVehicle('car', 'diesel'); + moto = createVehicle('moto', 'diesel'); + bus = createVehicle('bus', undefined, 20); + boat = createVehicle('boat', undefined, 300, true); + bicycle = createVehicle('bicycle'); +} diff --git a/apps/typescript/overload/src/app/vehicle.utils.ts b/apps/typescript/15-function-overload/src/app/vehicle.utils.ts similarity index 100% rename from apps/typescript/overload/src/app/vehicle.utils.ts rename to apps/typescript/15-function-overload/src/app/vehicle.utils.ts diff --git a/apps/ngrx/effect-selector/src/styles.scss b/apps/typescript/15-function-overload/src/assets/.gitkeep similarity index 100% rename from apps/ngrx/effect-selector/src/styles.scss rename to apps/typescript/15-function-overload/src/assets/.gitkeep diff --git a/apps/typescript/15-function-overload/src/favicon.ico b/apps/typescript/15-function-overload/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/typescript/15-function-overload/src/favicon.ico differ diff --git a/apps/typescript/15-function-overload/src/index.html b/apps/typescript/15-function-overload/src/index.html new file mode 100644 index 000000000..37dd3a978 --- /dev/null +++ b/apps/typescript/15-function-overload/src/index.html @@ -0,0 +1,13 @@ + + + + + typescript-function-overload + + + + + + + + diff --git a/apps/typescript/15-function-overload/src/main.ts b/apps/typescript/15-function-overload/src/main.ts new file mode 100644 index 000000000..63574fdcf --- /dev/null +++ b/apps/typescript/15-function-overload/src/main.ts @@ -0,0 +1,7 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, { + providers: [provideZoneChangeDetection()], +}).catch((err) => console.error(err)); diff --git a/apps/testing/nested/src/styles.scss b/apps/typescript/15-function-overload/src/styles.scss similarity index 100% rename from apps/testing/nested/src/styles.scss rename to apps/typescript/15-function-overload/src/styles.scss diff --git a/apps/typescript/15-function-overload/tsconfig.app.json b/apps/typescript/15-function-overload/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/typescript/15-function-overload/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/typescript/enums-vs-union-types/tsconfig.editor.json b/apps/typescript/15-function-overload/tsconfig.editor.json similarity index 100% rename from apps/typescript/enums-vs-union-types/tsconfig.editor.json rename to apps/typescript/15-function-overload/tsconfig.editor.json diff --git a/apps/typescript/15-function-overload/tsconfig.json b/apps/typescript/15-function-overload/tsconfig.json new file mode 100644 index 000000000..ca3ea3c79 --- /dev/null +++ b/apps/typescript/15-function-overload/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/typescript/47-enums-vs-union-types/.eslintrc.json b/apps/typescript/47-enums-vs-union-types/.eslintrc.json new file mode 100644 index 000000000..8ebcbfd59 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/typescript/enums-vs-union-types/README.md b/apps/typescript/47-enums-vs-union-types/README.md similarity index 100% rename from apps/typescript/enums-vs-union-types/README.md rename to apps/typescript/47-enums-vs-union-types/README.md diff --git a/apps/typescript/47-enums-vs-union-types/project.json b/apps/typescript/47-enums-vs-union-types/project.json new file mode 100644 index 000000000..e5c3283d6 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/project.json @@ -0,0 +1,70 @@ +{ + "name": "typescript-enums-vs-union-types", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/typescript/47-enums-vs-union-types/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/typescript/47-enums-vs-union-types", + "index": "apps/typescript/47-enums-vs-union-types/src/index.html", + "browser": "apps/typescript/47-enums-vs-union-types/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/typescript/47-enums-vs-union-types/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/typescript/47-enums-vs-union-types/src/favicon.ico", + "apps/typescript/47-enums-vs-union-types/src/assets" + ], + "styles": ["apps/typescript/47-enums-vs-union-types/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "typescript-enums-vs-union-types:build:production" + }, + "development": { + "buildTarget": "typescript-enums-vs-union-types:build:development" + } + }, + "defaultConfiguration": "development", + "continuous": true + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "typescript-enums-vs-union-types:build" + } + } + } +} diff --git a/apps/typescript/47-enums-vs-union-types/src/app/app.component.ts b/apps/typescript/47-enums-vs-union-types/src/app/app.component.ts new file mode 100644 index 000000000..05886724f --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/src/app/app.component.ts @@ -0,0 +1,82 @@ +import { Component, computed, signal } from '@angular/core'; + +enum Difficulty { + EASY = 'easy', + NORMAL = 'normal', +} + +enum Direction { + LEFT = 'left', + RIGHT = 'right', +} + +@Component({ + imports: [], + selector: 'app-root', + template: ` +
    +
    + + +
    +

    Selected Difficulty: {{ difficultyLabel() }}

    +
    + +
    +
    + + +
    +

    {{ directionLabel() }}

    +
    + `, + styles: ` + section { + @apply mx-auto my-5 flex w-fit flex-col items-center gap-2; + + > div { + @apply flex w-fit gap-5; + } + } + + button { + @apply rounded-md border px-4 py-2; + } + `, +}) +export class AppComponent { + readonly Difficulty = Difficulty; + readonly difficulty = signal(Difficulty.EASY); + + readonly Direction = Direction; + readonly direction = signal(undefined); + + readonly difficultyLabel = computed(() => { + switch (this.difficulty()) { + case Difficulty.EASY: + return Difficulty.EASY; + case Difficulty.NORMAL: + return Difficulty.NORMAL; + } + }); + + readonly directionLabel = computed(() => { + const prefix = 'You chose to go'; + switch (this.direction()) { + case Direction.LEFT: + return `${prefix} ${Direction.LEFT}`; + case Direction.RIGHT: + return `${prefix} ${Direction.RIGHT}`; + default: + return 'Choose a direction!'; + } + }); +} diff --git a/apps/typescript/47-enums-vs-union-types/src/app/app.config.ts b/apps/typescript/47-enums-vs-union-types/src/app/app.config.ts new file mode 100644 index 000000000..81a6edde4 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/typescript/47-enums-vs-union-types/src/assets/.gitkeep b/apps/typescript/47-enums-vs-union-types/src/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/apps/typescript/47-enums-vs-union-types/src/favicon.ico b/apps/typescript/47-enums-vs-union-types/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/typescript/47-enums-vs-union-types/src/favicon.ico differ diff --git a/apps/typescript/enums-vs-union-types/src/index.html b/apps/typescript/47-enums-vs-union-types/src/index.html similarity index 100% rename from apps/typescript/enums-vs-union-types/src/index.html rename to apps/typescript/47-enums-vs-union-types/src/index.html diff --git a/apps/typescript/47-enums-vs-union-types/src/main.ts b/apps/typescript/47-enums-vs-union-types/src/main.ts new file mode 100644 index 000000000..4919bb4e9 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/src/main.ts @@ -0,0 +1,9 @@ +import { provideZoneChangeDetection } from '@angular/core'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, { + ...appConfig, + providers: [provideZoneChangeDetection(), ...appConfig.providers], +}).catch((err) => console.error(err)); diff --git a/apps/typescript/47-enums-vs-union-types/src/styles.scss b/apps/typescript/47-enums-vs-union-types/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/typescript/47-enums-vs-union-types/tailwind.config.js b/apps/typescript/47-enums-vs-union-types/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/typescript/47-enums-vs-union-types/tsconfig.app.json b/apps/typescript/47-enums-vs-union-types/tsconfig.app.json new file mode 100644 index 000000000..8b5631268 --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [], + "moduleResolution": "bundler" + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/typescript/overload/tsconfig.editor.json b/apps/typescript/47-enums-vs-union-types/tsconfig.editor.json similarity index 100% rename from apps/typescript/overload/tsconfig.editor.json rename to apps/typescript/47-enums-vs-union-types/tsconfig.editor.json diff --git a/apps/typescript/47-enums-vs-union-types/tsconfig.json b/apps/typescript/47-enums-vs-union-types/tsconfig.json new file mode 100644 index 000000000..7cfcc3b0b --- /dev/null +++ b/apps/typescript/47-enums-vs-union-types/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve", + "moduleResolution": "bundler", + "lib": ["dom", "es2022"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/typescript/enums-vs-union-types/project.json b/apps/typescript/enums-vs-union-types/project.json deleted file mode 100644 index 63e9a04c0..000000000 --- a/apps/typescript/enums-vs-union-types/project.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "typescript-enums-vs-union-types", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "prefix": "app", - "sourceRoot": "apps/typescript/enums-vs-union-types/src", - "tags": [], - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:application", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/typescript/enums-vs-union-types", - "index": "apps/typescript/enums-vs-union-types/src/index.html", - "browser": "apps/typescript/enums-vs-union-types/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/typescript/enums-vs-union-types/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/typescript/enums-vs-union-types/src/favicon.ico", - "apps/typescript/enums-vs-union-types/src/assets" - ], - "styles": ["apps/typescript/enums-vs-union-types/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "optimization": false, - "extractLicenses": false, - "sourceMap": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "typescript-enums-vs-union-types:build:production" - }, - "development": { - "buildTarget": "typescript-enums-vs-union-types:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "typescript-enums-vs-union-types:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - } - } -} diff --git a/apps/typescript/enums-vs-union-types/src/app/app.component.ts b/apps/typescript/enums-vs-union-types/src/app/app.component.ts deleted file mode 100644 index d82470519..000000000 --- a/apps/typescript/enums-vs-union-types/src/app/app.component.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Component, computed, signal } from '@angular/core'; - -enum Difficulty { - EASY = 'easy', - NORMAL = 'normal', -} - -enum Direction { - LEFT = 'left', - RIGHT = 'right', -} - -@Component({ - standalone: true, - imports: [], - selector: 'app-root', - template: ` -
    -
    - - -
    -

    Selected Difficulty: {{ difficultyLabel() }}

    -
    - -
    -
    - - -
    -

    {{ directionLabel() }}

    -
    - `, - styles: ` - section { - @apply flex flex-col mx-auto my-5 w-fit gap-2 items-center; - - > div { - @apply flex w-fit gap-5; - } - } - - button { - @apply rounded-md border px-4 py-2; - } - `, -}) -export class AppComponent { - readonly Difficulty = Difficulty; - readonly difficulty = signal(Difficulty.EASY); - - readonly Direction = Direction; - readonly direction = signal(undefined); - - readonly difficultyLabel = computed(() => { - switch (this.difficulty()) { - case Difficulty.EASY: - return Difficulty.EASY; - case Difficulty.NORMAL: - return Difficulty.NORMAL; - } - }); - - readonly directionLabel = computed(() => { - const prefix = 'You chose to go'; - switch (this.direction()) { - case Direction.LEFT: - return `${prefix} ${Direction.LEFT}`; - case Direction.RIGHT: - return `${prefix} ${Direction.RIGHT}`; - default: - return 'Choose a direction!'; - } - }); -} diff --git a/apps/typescript/enums-vs-union-types/src/main.ts b/apps/typescript/enums-vs-union-types/src/main.ts deleted file mode 100644 index f3a7223da..000000000 --- a/apps/typescript/enums-vs-union-types/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err), -); diff --git a/apps/typescript/enums-vs-union-types/tsconfig.app.json b/apps/typescript/enums-vs-union-types/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/typescript/enums-vs-union-types/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/typescript/enums-vs-union-types/tsconfig.json b/apps/typescript/enums-vs-union-types/tsconfig.json deleted file mode 100644 index db0ec0f25..000000000 --- a/apps/typescript/enums-vs-union-types/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json", - }, - { - "path": "./tsconfig.editor.json", - }, - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true, - }, -} diff --git a/apps/typescript/overload/.eslintrc.json b/apps/typescript/overload/.eslintrc.json deleted file mode 100644 index bf8df1428..000000000 --- a/apps/typescript/overload/.eslintrc.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "extends": ["../../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "rules": { - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ] - }, - "extends": [ - "plugin:@nx/angular", - "plugin:@angular-eslint/template/process-inline-templates" - ] - }, - { - "files": ["*.html"], - "extends": ["plugin:@nx/angular-template"], - "rules": {} - } - ] -} diff --git a/apps/typescript/overload/README.md b/apps/typescript/overload/README.md deleted file mode 100644 index b4336af99..000000000 --- a/apps/typescript/overload/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Function Overload - -> author: thomas-laforge - -### Run Application - -```bash -npx nx serve typescript-overload` -``` - -### Documentation and Instruction - -Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/typescript/15-typescript-overload-fn/). diff --git a/apps/typescript/overload/project.json b/apps/typescript/overload/project.json deleted file mode 100644 index 397c71bc1..000000000 --- a/apps/typescript/overload/project.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "typescript-overload", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "apps/typescript/overload/src", - "prefix": "app", - "targets": { - "build": { - "executor": "@angular-devkit/build-angular:browser", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/apps/typescript/overload", - "index": "apps/typescript/overload/src/index.html", - "main": "apps/typescript/overload/src/main.ts", - "polyfills": ["zone.js"], - "tsConfig": "apps/typescript/overload/tsconfig.app.json", - "inlineStyleLanguage": "scss", - "assets": [ - "apps/typescript/overload/src/favicon.ico", - "apps/typescript/overload/src/assets" - ], - "styles": ["apps/typescript/overload/src/styles.scss"], - "scripts": [] - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" - }, - { - "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" - } - ], - "outputHashing": "all" - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "executor": "@angular-devkit/build-angular:dev-server", - "configurations": { - "production": { - "buildTarget": "typescript-overload:build:production" - }, - "development": { - "buildTarget": "typescript-overload:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "executor": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "typescript-overload:build" - } - }, - "lint": { - "executor": "@nx/eslint:lint" - } - }, - "tags": [] -} diff --git a/apps/typescript/overload/src/app/app.component.ts b/apps/typescript/overload/src/app/app.component.ts deleted file mode 100644 index 3ea2a7131..000000000 --- a/apps/typescript/overload/src/app/app.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; -import { createVehicle } from './vehicle.utils'; - -@Component({ - standalone: true, - selector: 'app-root', - template: ``, -}) -export class AppComponent { - car = createVehicle('car', 'diesel'); - moto = createVehicle('moto', 'diesel'); - bus = createVehicle('bus', undefined, 20); - boat = createVehicle('boat', undefined, 300, true); - bicycle = createVehicle('bicycle'); -} diff --git a/apps/typescript/overload/src/index.html b/apps/typescript/overload/src/index.html deleted file mode 100644 index 86561b663..000000000 --- a/apps/typescript/overload/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Overload - - - - - - - - diff --git a/apps/typescript/overload/src/main.ts b/apps/typescript/overload/src/main.ts deleted file mode 100644 index 31c5da482..000000000 --- a/apps/typescript/overload/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/typescript/overload/src/styles.scss b/apps/typescript/overload/src/styles.scss deleted file mode 100644 index 90d4ee007..000000000 --- a/apps/typescript/overload/src/styles.scss +++ /dev/null @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/apps/typescript/overload/tsconfig.app.json b/apps/typescript/overload/tsconfig.app.json deleted file mode 100644 index 58220429a..000000000 --- a/apps/typescript/overload/tsconfig.app.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "types": [] - }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] -} diff --git a/apps/typescript/overload/tsconfig.json b/apps/typescript/overload/tsconfig.json deleted file mode 100644 index 51c7908c5..000000000 --- a/apps/typescript/overload/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], - "extends": "../../../tsconfig.base.json", - "angularCompilerOptions": { - "enableI18nLegacyMessageIdFormat": false, - "strictInjectionParameters": true, - "strictInputAccessModifiers": true, - "strictTemplates": true - } -} diff --git a/challenge-number.json b/challenge-number.json index fee6a9627..9c2da549a 100644 --- a/challenge-number.json +++ b/challenge-number.json @@ -1,6 +1,6 @@ { - "total": 47, - "🟢": 18, - "🟠": 120, - "🔴": 209 + "total": 61, + "🟢": 24, + "🟠": 124, + "🔴": 212 } diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 25d1048bc..000000000 --- a/docs/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Starlight Starter Kit: Basics - -``` -npm create astro@latest -- --template starlight -``` - -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) - -> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! - -## 🚀 Project Structure - -Inside of your Astro + Starlight project, you'll see the following folders and files: - -``` -. -├── public/ -├── src/ -│ ├── assets/ -│ ├── content/ -│ │ ├── docs/ -│ │ └── config.ts -│ └── env.d.ts -├── astro.config.mjs -├── package.json -└── tsconfig.json -``` - -Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. - -Images can be added to `src/assets/` and embedded in Markdown with a relative link. - -Static assets, like favicons, can be placed in the `public/` directory. - -## 🧞 Commands - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `npm ci` | Installs dependencies | -| `npm run dev` | Starts local dev server at `localhost:4321` | -| `npm run build` | Build your production site to `./dist/` | -| `npm run preview` | Preview your build locally, before deploying | -| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | -| `npm run astro -- --help` | Get help using the Astro CLI | - -## 👀 Want to learn more? - -Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). -f diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index bce29de09..953462156 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -23,6 +23,10 @@ export const locales = { ru: { label: 'Русский', lang: 'ru' + }, + 'zh-cn': { + label: '简体中文', + lang: 'zh-CN' } }; @@ -51,7 +55,8 @@ export default defineConfig({ es: 'Guías', fr: 'Guides', pt: 'Guias', - ru: 'Руководство' + ru: 'Руководство', + 'zh-CN': '指南' } }, { @@ -63,8 +68,9 @@ export default defineConfig({ translations: { es: 'Leaderboard', fr: 'Leaderboard', - pt: 'Leaderboard', - ru: 'Leaderboard' + pt: 'Tabela de Classificação', + ru: 'Leaderboard', + 'zh-CN': '排行榜' } }, { @@ -76,7 +82,8 @@ export default defineConfig({ es: 'Desafíos', fr: 'Challenges', pt: 'Desafios', - ru: 'Задачи' + ru: 'Задачи', + 'zh-CN': '挑战' } }], head: [{ diff --git a/docs/package-lock.json b/docs/package-lock.json deleted file mode 100644 index 626127ffe..000000000 --- a/docs/package-lock.json +++ /dev/null @@ -1,11186 +0,0 @@ -{ - "name": "angular-challenges-docs", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "angular-challenges-docs", - "version": "0.0.1", - "dependencies": { - "@astrojs/starlight": "^0.15.1", - "@astrojs/svelte": "^5.2.0", - "@astrojs/vercel": "^7.5.0", - "@fontsource/ibm-plex-serif": "^5.0.8", - "astro": "^4.0.0", - "sharp": "^0.32.5", - "svelte": "^4.2.12", - "typescript": "^5.4.3" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@astrojs/compiler": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.7.0.tgz", - "integrity": "sha512-XpC8MAaWjD1ff6/IfkRq/5k1EFj6zhCNqXRd5J43SVJEBj/Bsmizkm8N0xOYscGcDFQkRgEw6/eKnI5x/1l6aA==" - }, - "node_modules/@astrojs/internal-helpers": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.4.0.tgz", - "integrity": "sha512-6B13lz5n6BrbTqCTwhXjJXuR1sqiX/H6rTxzlXx+lN1NnV4jgnq/KJldCQaUWJzPL5SiWahQyinxAbxQtwgPHA==" - }, - "node_modules/@astrojs/markdown-remark": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-4.0.1.tgz", - "integrity": "sha512-RU4ESnqvyLpj8WZs0n5elS6idaDdtIIm7mIpMaRNPCebpxMjfcfdwcmBwz83ktAj5d2eO5bC3z92TcGdli+lRw==", - "dependencies": { - "@astrojs/prism": "^3.0.0", - "github-slugger": "^2.0.0", - "import-meta-resolve": "^4.0.0", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.0", - "remark-gfm": "^4.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "remark-smartypants": "^2.0.0", - "shikiji": "^0.6.13", - "unified": "^11.0.4", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.1" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@astrojs/markdown-remark/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/markdown-remark/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-2.0.1.tgz", - "integrity": "sha512-lWbiNoVV/6DO8hAf6eZmcN28hY/herif9eglw2PXZ5lEPoRu175BvBtuNTt9rH9YA/Ldm5mkNXhvMWNEnMqJkw==", - "dependencies": { - "@astrojs/markdown-remark": "4.0.1", - "@mdx-js/mdx": "^3.0.0", - "acorn": "^8.11.2", - "es-module-lexer": "^1.4.1", - "estree-util-visit": "^2.0.0", - "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", - "hast-util-to-html": "^9.0.0", - "kleur": "^4.1.4", - "rehype-raw": "^7.0.0", - "remark-gfm": "^4.0.0", - "remark-smartypants": "^2.0.0", - "source-map": "^0.7.4", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.1" - }, - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "astro": "^4.0.0" - } - }, - "node_modules/@astrojs/mdx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@astrojs/mdx/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/mdx/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/prism": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.0.0.tgz", - "integrity": "sha512-g61lZupWq1bYbcBnYZqdjndShr/J3l/oFobBKPA3+qMat146zce3nz2kdO4giGbhYDt4gYdhmoBz0vZJ4sIurQ==", - "dependencies": { - "prismjs": "^1.29.0" - }, - "engines": { - "node": ">=18.14.1" - } - }, - "node_modules/@astrojs/sitemap": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.0.3.tgz", - "integrity": "sha512-+GRKp1yho9dpHBcMcU6JpbL41k0yYZghOkNsMRb8QIRflbGHvd787tdv9oIZ5NJj0SqAuOlqp2UpqLkJXuAe2A==", - "dependencies": { - "sitemap": "^7.1.1", - "zod": "^3.22.4" - } - }, - "node_modules/@astrojs/starlight": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.15.1.tgz", - "integrity": "sha512-5AdySPQOG/+r1vHSNotQAGqhQIfF68hS8PfV+z4M2ewnrWoeCsHI3yYRFYgSRsVofcOEGTHiIryTRG/uRIvDkQ==", - "dependencies": { - "@astrojs/mdx": "^2.0.0", - "@astrojs/sitemap": "^3.0.3", - "@pagefind/default-ui": "^1.0.3", - "@types/hast": "^3.0.3", - "@types/mdast": "^4.0.3", - "astro-expressive-code": "^0.30.1", - "bcp-47": "^2.1.0", - "execa": "^8.0.1", - "hast-util-select": "^6.0.2", - "hastscript": "^8.0.0", - "mdast-util-directive": "^3.0.0", - "pagefind": "^1.0.3", - "rehype": "^13.0.1", - "remark-directive": "^3.0.0", - "unified": "^11.0.4", - "unist-util-remove": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.1" - }, - "peerDependencies": { - "astro": "^4.0.0" - } - }, - "node_modules/@astrojs/starlight/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@astrojs/starlight/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/starlight/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@astrojs/svelte": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/svelte/-/svelte-5.2.0.tgz", - "integrity": "sha512-GmwbXks2WMkmAfl0rlPM/2gA1RtmZzjGV2mOceV3g7QNyjIsSYBPKrlEnSFnuR+YMvlAtWdbMFBsb3gtGxnTTg==", - "dependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte2tsx": "^0.6.27" - }, - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "astro": "^4.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.56", - "typescript": "^5.3.3" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.1.tgz", - "integrity": "sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.1.tgz", - "integrity": "sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.1.tgz", - "integrity": "sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.1.tgz", - "integrity": "sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.1.tgz", - "integrity": "sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.1.tgz", - "integrity": "sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.1.tgz", - "integrity": "sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.1.tgz", - "integrity": "sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.1.tgz", - "integrity": "sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.1.tgz", - "integrity": "sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.1.tgz", - "integrity": "sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.1.tgz", - "integrity": "sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.1.tgz", - "integrity": "sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@astrojs/svelte/node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz", - "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "svelte-hmr": "^0.15.3", - "vitefu": "^0.2.5" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@astrojs/svelte/node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.0.0.tgz", - "integrity": "sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@astrojs/svelte/node_modules/@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@astrojs/svelte/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "hasInstallScript": true, - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/@astrojs/svelte/node_modules/rollup": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.1.tgz", - "integrity": "sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg==", - "peer": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.1", - "@rollup/rollup-android-arm64": "4.13.1", - "@rollup/rollup-darwin-arm64": "4.13.1", - "@rollup/rollup-darwin-x64": "4.13.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.1", - "@rollup/rollup-linux-arm64-gnu": "4.13.1", - "@rollup/rollup-linux-arm64-musl": "4.13.1", - "@rollup/rollup-linux-riscv64-gnu": "4.13.1", - "@rollup/rollup-linux-s390x-gnu": "4.13.1", - "@rollup/rollup-linux-x64-gnu": "4.13.1", - "@rollup/rollup-linux-x64-musl": "4.13.1", - "@rollup/rollup-win32-arm64-msvc": "4.13.1", - "@rollup/rollup-win32-ia32-msvc": "4.13.1", - "@rollup/rollup-win32-x64-msvc": "4.13.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/@astrojs/svelte/node_modules/vite": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.6.tgz", - "integrity": "sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==", - "peer": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.36", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/@astrojs/telemetry": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.4.tgz", - "integrity": "sha512-A+0c7k/Xy293xx6odsYZuXiaHO0PL+bnDoXOc47sGDF5ffIKdKQGRPFl2NMlCF4L0NqN4Ynbgnaip+pPF0s7pQ==", - "dependencies": { - "ci-info": "^3.8.0", - "debug": "^4.3.4", - "dlv": "^1.1.3", - "dset": "^3.1.2", - "is-docker": "^3.0.0", - "is-wsl": "^3.0.0", - "which-pm-runs": "^1.1.0" - }, - "engines": { - "node": ">=18.14.1" - } - }, - "node_modules/@astrojs/telemetry/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/@astrojs/vercel": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@astrojs/vercel/-/vercel-7.5.0.tgz", - "integrity": "sha512-RYFZNHkfNgFNb41nblG26ubw5924hAjLYs+Bpp4kttcsYJAX/wavIfDbfZQ/XesDTKwIH+Gi/+3c5bldZePFDA==", - "dependencies": { - "@astrojs/internal-helpers": "0.4.0", - "@vercel/analytics": "^1.0.2", - "@vercel/edge": "^1.1.1", - "@vercel/nft": "^0.26.4", - "esbuild": "^0.19.6", - "fast-glob": "^3.3.2", - "set-cookie-parser": "^2.6.0", - "web-vitals": "^3.4.0" - }, - "peerDependencies": { - "astro": "^4.2.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "dependencies": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", - "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.1", - "@babel/parser": "^7.24.1", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", - "dependencies": { - "@babel/types": "^7.24.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", - "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", - "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz", - "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", - "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", - "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", - "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", - "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", - "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", - "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", - "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", - "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", - "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", - "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", - "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", - "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", - "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", - "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", - "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", - "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", - "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", - "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", - "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", - "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", - "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", - "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", - "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", - "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@expressive-code/core": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.30.1.tgz", - "integrity": "sha512-z11G1lfzzuTJ63C4dGPUIEKxJse5eKrVxqxQJRiuCDH8hPqfIQs/+by04UceSWB0dt5SIFsL5J+7HvCycbc1iA==", - "dependencies": { - "@ctrl/tinycolor": "^3.6.0", - "hast-util-to-html": "^8.0.4", - "hastscript": "^7.2.0", - "postcss": "^8.4.21", - "postcss-nested": "^6.0.1" - } - }, - "node_modules/@expressive-code/core/node_modules/@types/hast": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", - "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-to-html": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", - "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^7.0.0", - "hast-util-whitespace": "^2.0.0", - "html-void-elements": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@expressive-code/core/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/@expressive-code/core/node_modules/unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/core/node_modules/vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/plugin-frames": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.30.1.tgz", - "integrity": "sha512-fBqd+NWcmlP63q8kNi73b6EuwWZwb+8OIhqWEsEQ/lsoOmT8FVYqsnH+M+TRC9or+U0PNd7Po/ojcFNnS0TAIQ==", - "dependencies": { - "@expressive-code/core": "^0.30.1", - "hastscript": "^7.2.0" - } - }, - "node_modules/@expressive-code/plugin-frames/node_modules/@types/hast": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", - "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@expressive-code/plugin-frames/node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/plugin-frames/node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/plugin-shiki": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.30.1.tgz", - "integrity": "sha512-VoJZWZ1wjW/I+CsHg4/RwurrHdtnF5C5fbXESQCQlnXWOhWBfJnOX1ilx5B11gsH5kEWNoD5WRAt8t0L0V/VJA==", - "dependencies": { - "@expressive-code/core": "^0.30.1", - "shikiji": "^0.8.0" - } - }, - "node_modules/@expressive-code/plugin-shiki/node_modules/shikiji": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.8.7.tgz", - "integrity": "sha512-j5usxwI0yHkDTHOuhuSJl9+wT5CNYeYO82dJMSJBlJ/NYT5SIebGcPoL6y9QOyH15wGrJC4LOP2nz5k8mUDGRQ==", - "dependencies": { - "hast-util-to-html": "^9.0.0" - } - }, - "node_modules/@expressive-code/plugin-text-markers": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.30.1.tgz", - "integrity": "sha512-Dtw2lIsAfcfWy/qUhrEW1NwZdgMsI+qeHQ/7Do+W9fMBIoIIHh2GLwmhwkBitoOvLgOJQWsNoBvT42LUp2+16g==", - "dependencies": { - "@expressive-code/core": "^0.30.1", - "hastscript": "^7.2.0", - "unist-util-visit-parents": "^5.1.3" - } - }, - "node_modules/@expressive-code/plugin-text-markers/node_modules/@types/hast": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", - "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@expressive-code/plugin-text-markers/node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@expressive-code/plugin-text-markers/node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@fontsource/ibm-plex-serif": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-serif/-/ibm-plex-serif-5.0.8.tgz", - "integrity": "sha512-KUp1E9Wzf2Umhr2SbpcF9HwgFJmuxvKAARmpl7GDDkIG30R1PMFJWxfSfQ7oX/oVBtomGq5RUTaMMUeE0ngEgw==" - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", - "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@mdx-js/mdx/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/mdx/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pagefind/darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.0.3.tgz", - "integrity": "sha512-vsHDtvao3W4iFCxVc4S0BVhpj3E2MAoIVM7RmuQfGp1Ng22nGLRaMP6FguLO8TMabRJdvp4SVr227hL4WGKOHA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.0.3.tgz", - "integrity": "sha512-NhEXHHYmB/hT6lx5rCcmnVTxH+uIkMAd43bzEqMwHQosqTZEIQfwihmV39H+m8yo7jFvz3zRbJNzhAh7G4PiwA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/default-ui": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.0.3.tgz", - "integrity": "sha512-WieFJXvezyvjZh49I8j7a7Kz3LsXYY2Uep3IWvG5NG05mmiurURXjXc+KyrpIp/iAycSnjrC1TDJ8CdES/ee3A==" - }, - "node_modules/@pagefind/linux-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.0.3.tgz", - "integrity": "sha512-RGsMt4AmGT8WxCSeP09arU7Za6Vf/We4TWHVSbY7vDMuwWql9Ngoib/q1cP9dIAIMdkXh9ePG/S3mGnJYsdzuQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/linux-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.0.3.tgz", - "integrity": "sha512-o+VCKaqImL42scSH1n5gUfppYSNyu3BuGTvtKKgWHmycbL+A3fkFH+ZOFbaLeN7LVTvJqJIOYbk4j2yaq9784Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/windows-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.0.3.tgz", - "integrity": "sha512-S+Yq4FyvXJm4F+iN/wRiLvEEF8Xs9lTKGtQGaRHXJslQyl65dytDDPIULXJXIadrDbnMrnTt4C2YHmEUIyUIHg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.2.tgz", - "integrity": "sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.2.tgz", - "integrity": "sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.2.tgz", - "integrity": "sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.2.tgz", - "integrity": "sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.2.tgz", - "integrity": "sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.2.tgz", - "integrity": "sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.2.tgz", - "integrity": "sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.13.2.tgz", - "integrity": "sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ==", - "cpu": [ - "ppc64le" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.2.tgz", - "integrity": "sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.1.tgz", - "integrity": "sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.2.tgz", - "integrity": "sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.2.tgz", - "integrity": "sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.2.tgz", - "integrity": "sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.2.tgz", - "integrity": "sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.2.tgz", - "integrity": "sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.2.1.tgz", - "integrity": "sha512-KaIS0H4EQ3KI2d++TjYqRNgwp8E3M/68e9veR4QtInzA7kKFgcjeiJqb80fuXW+blDy5fmd11PN9g9soz/3ANQ==" - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", - "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "node_modules/@types/nlcst": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-1.0.2.tgz", - "integrity": "sha512-ykxL/GDDUhqikjU0LIywZvEwb1NTYXTEWf+XgMSS2o6IXIakafPccxZmxgZcvJPZ3yFl2kdL1gJZz3U3iZF3QA==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", - "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@vercel/analytics": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.2.tgz", - "integrity": "sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==", - "dependencies": { - "server-only": "^0.0.1" - }, - "peerDependencies": { - "next": ">= 13", - "react": "^18 || ^19" - }, - "peerDependenciesMeta": { - "next": { - "optional": true - }, - "react": { - "optional": true - } - } - }, - "node_modules/@vercel/edge": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@vercel/edge/-/edge-1.1.1.tgz", - "integrity": "sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==" - }, - "node_modules/@vercel/nft": { - "version": "0.26.4", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.26.4.tgz", - "integrity": "sha512-j4jCOOXke2t8cHZCIxu1dzKLHLcFmYzC3yqAK6MfZznOL1QIJKd0xcFsXK3zcqzU7ScsE2zWkiMMNHGMHgp+FA==", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.5", - "@rollup/pluginutils": "^4.0.0", - "acorn": "^8.6.0", - "acorn-import-attributes": "^1.9.2", - "async-sema": "^3.1.1", - "bindings": "^1.4.0", - "estree-walker": "2.0.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.2", - "node-gyp-build": "^4.2.2", - "resolve-from": "^5.0.0" - }, - "bin": { - "nft": "out/cli.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@vercel/nft/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.4.tgz", - "integrity": "sha512-dNIX/5UEnZvVL94dV2scl4VIooK36D8AteP4xiz7cPKhDbhLhSuWkzG580g+Q7TXJklp+Z21SiaK7/HpLO84Qg==", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/astro": { - "version": "4.5.12", - "resolved": "https://registry.npmjs.org/astro/-/astro-4.5.12.tgz", - "integrity": "sha512-xIJcFI2hbyV8+h5pWjL7SKD1jIP0K01fYVAH+gdAt0mJaXy+u8Mj+goD0cPlK6sEaykR+7zxQLYGKJ44U4qarg==", - "dependencies": { - "@astrojs/compiler": "^2.7.0", - "@astrojs/internal-helpers": "0.4.0", - "@astrojs/markdown-remark": "4.3.2", - "@astrojs/telemetry": "3.0.4", - "@babel/core": "^7.24.3", - "@babel/generator": "^7.23.3", - "@babel/parser": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "@types/babel__core": "^7.20.4", - "acorn": "^8.11.2", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "boxen": "^7.1.1", - "chokidar": "^3.5.3", - "ci-info": "^4.0.0", - "clsx": "^2.0.0", - "common-ancestor-path": "^1.0.1", - "cookie": "^0.6.0", - "cssesc": "^3.0.0", - "debug": "^4.3.4", - "deterministic-object-hash": "^2.0.1", - "devalue": "^4.3.2", - "diff": "^5.1.0", - "dlv": "^1.1.3", - "dset": "^3.1.3", - "es-module-lexer": "^1.4.1", - "esbuild": "^0.19.6", - "estree-walker": "^3.0.3", - "execa": "^8.0.1", - "fast-glob": "^3.3.2", - "flattie": "^1.1.0", - "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", - "html-escaper": "^3.0.3", - "http-cache-semantics": "^4.1.1", - "js-yaml": "^4.1.0", - "kleur": "^4.1.4", - "magic-string": "^0.30.3", - "mime": "^3.0.0", - "ora": "^7.0.1", - "p-limit": "^5.0.0", - "p-queue": "^8.0.1", - "path-to-regexp": "^6.2.1", - "preferred-pm": "^3.1.2", - "prompts": "^2.4.2", - "rehype": "^13.0.1", - "resolve": "^1.22.4", - "semver": "^7.5.4", - "shiki": "^1.1.2", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0", - "tsconfck": "^3.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.1", - "vite": "^5.1.4", - "vitefu": "^0.2.5", - "which-pm": "^2.1.1", - "yargs-parser": "^21.1.1", - "zod": "^3.22.4", - "zod-to-json-schema": "^3.22.4" - }, - "bin": { - "astro": "astro.js" - }, - "engines": { - "node": ">=18.14.1", - "npm": ">=6.14.0" - }, - "optionalDependencies": { - "sharp": "^0.32.6" - } - }, - "node_modules/astro-expressive-code": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.30.1.tgz", - "integrity": "sha512-Dr3VbK4HvIXTT8rsvd8PuRW4uZOpfRz9J8noVSSxmx7/M7o73SBtqauBYvxXpGHnagTJPGzYOa9BQS7jDHNUVw==", - "dependencies": { - "remark-expressive-code": "^0.30.1" - }, - "peerDependencies": { - "astro": "^3.3.0 || ^4.0.0-beta" - } - }, - "node_modules/astro/node_modules/@astrojs/markdown-remark": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-4.3.2.tgz", - "integrity": "sha512-4Oa4VaYiBd0MatB+rWIU/0A8pZH/sK3c2QkRYb+OO2lPl+qzevJtWaZY8hAQc4qurIOlRdn6B6ofDAGhWw+DSg==", - "dependencies": { - "@astrojs/prism": "^3.0.0", - "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "import-meta-resolve": "^4.0.0", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.0", - "remark-gfm": "^4.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "remark-smartypants": "^2.0.0", - "shiki": "^1.1.2", - "unified": "^11.0.4", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.1" - } - }, - "node_modules/astro/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/astro/node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.2.tgz", - "integrity": "sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/astro/node_modules/@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/astro/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/astro/node_modules/rollup": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.2.tgz", - "integrity": "sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==", - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.2", - "@rollup/rollup-android-arm64": "4.13.2", - "@rollup/rollup-darwin-arm64": "4.13.2", - "@rollup/rollup-darwin-x64": "4.13.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.2", - "@rollup/rollup-linux-arm64-gnu": "4.13.2", - "@rollup/rollup-linux-arm64-musl": "4.13.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.13.2", - "@rollup/rollup-linux-riscv64-gnu": "4.13.2", - "@rollup/rollup-linux-s390x-gnu": "4.13.2", - "@rollup/rollup-linux-x64-gnu": "4.13.2", - "@rollup/rollup-linux-x64-musl": "4.13.2", - "@rollup/rollup-win32-arm64-msvc": "4.13.2", - "@rollup/rollup-win32-ia32-msvc": "4.13.2", - "@rollup/rollup-win32-x64-msvc": "4.13.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/astro/node_modules/string-width": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", - "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/astro/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/astro/node_modules/vite": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.6.tgz", - "integrity": "sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==", - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.36", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/astro/node_modules/vite/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/async-sema": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", - "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==" - }, - "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcp-47": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", - "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/bcp-47-match": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", - "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/boxen/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/boxen/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", - "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-selector-parser": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.4.tgz", - "integrity": "sha512-pnmS1dbKsz6KA4EW4BznyPL2xxkNDRg62hcD0v8g6DEw2W7hxOln5M953jsp9hmw5Dg57S6o/A8GOn37mbAgcQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dedent-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", - "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==" - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/deterministic-object-hash": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", - "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", - "dependencies": { - "base-64": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/direction": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", - "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", - "bin": { - "direction": "cli.js" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dset": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", - "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.615", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", - "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==" - }, - "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" - }, - "node_modules/esbuild": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", - "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.10", - "@esbuild/android-arm": "0.19.10", - "@esbuild/android-arm64": "0.19.10", - "@esbuild/android-x64": "0.19.10", - "@esbuild/darwin-arm64": "0.19.10", - "@esbuild/darwin-x64": "0.19.10", - "@esbuild/freebsd-arm64": "0.19.10", - "@esbuild/freebsd-x64": "0.19.10", - "@esbuild/linux-arm": "0.19.10", - "@esbuild/linux-arm64": "0.19.10", - "@esbuild/linux-ia32": "0.19.10", - "@esbuild/linux-loong64": "0.19.10", - "@esbuild/linux-mips64el": "0.19.10", - "@esbuild/linux-ppc64": "0.19.10", - "@esbuild/linux-riscv64": "0.19.10", - "@esbuild/linux-s390x": "0.19.10", - "@esbuild/linux-x64": "0.19.10", - "@esbuild/netbsd-x64": "0.19.10", - "@esbuild/openbsd-x64": "0.19.10", - "@esbuild/sunos-x64": "0.19.10", - "@esbuild/win32-arm64": "0.19.10", - "@esbuild/win32-ia32": "0.19.10", - "@esbuild/win32-x64": "0.19.10" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/expressive-code": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.30.1.tgz", - "integrity": "sha512-iD8xtfN8X29jfk0B2U4/ws1pV/8GgRVIGOIDm9f6U9Zcnse1OnD/i+cYkcaOr5MLpVe8eLEr8GvVtZDOBxekrg==", - "dependencies": { - "@expressive-code/core": "^0.30.1", - "@expressive-code/plugin-frames": "^0.30.1", - "@expressive-code/plugin-shiki": "^0.30.1", - "@expressive-code/plugin-text-markers": "^0.30.1" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "dependencies": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" - } - }, - "node_modules/flattie": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.0.tgz", - "integrity": "sha512-xU99gDEnciIwJdGcBmNHnzTJ/w5AT+VFJOu6sTB6WM8diOYNA3Sa+K1DiEBQ7XH4QikQq3iFW1U+jRVcotQnBw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/gauge/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "node_modules/hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-from-html/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-has-property": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", - "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", - "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-raw/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.2.tgz", - "integrity": "sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "bcp-47-match": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "css-selector-parser": "^3.0.0", - "devlop": "^1.0.0", - "direction": "^2.0.0", - "hast-util-has-property": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "not": "^0.1.0", - "nth-check": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-select/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.0.tgz", - "integrity": "sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^9.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", - "dependencies": { - "inline-style-parser": "0.2.2" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz", - "integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.0.tgz", - "integrity": "sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/load-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/load-yaml-file/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/load-yaml-file/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", - "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-definitions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", - "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-directive/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-mdx-jsx/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", - "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/micromark-factory-mdx-expression/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/micromark-util-events-to-acorn/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, - "node_modules/nlcst-to-string": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", - "integrity": "sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==", - "dependencies": { - "@types/nlcst": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-abi": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", - "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/not": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", - "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" - }, - "node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", - "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", - "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.9.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.3.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.0.1.tgz", - "integrity": "sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==", - "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", - "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pagefind": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.0.3.tgz", - "integrity": "sha512-ws7kmMxW6OuxzsOjj3YAx6TYq/54MiE3wfyBM3J5CInbZyBBvM2Z8c8IYvnMkBcb5v2EoB9DewXEekOEiDRu5g==", - "bin": { - "pagefind": "lib/runner/bin.cjs" - }, - "optionalDependencies": { - "@pagefind/darwin-arm64": "1.0.3", - "@pagefind/darwin-x64": "1.0.3", - "@pagefind/linux-arm64": "1.0.3", - "@pagefind/linux-x64": "1.0.3", - "@pagefind/windows-x64": "1.0.3" - } - }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-latin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", - "integrity": "sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==", - "dependencies": { - "nlcst-to-string": "^3.0.0", - "unist-util-modify-children": "^3.0.0", - "unist-util-visit-children": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/prebuild-install/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/preferred-pm": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.1.2.tgz", - "integrity": "sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==", - "dependencies": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/preferred-pm/node_modules/which-pm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", - "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", - "dependencies": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8.15" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prompts/node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/property-information": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.3.0.tgz", - "integrity": "sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rehype": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.1.tgz", - "integrity": "sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==", - "dependencies": { - "@types/hast": "^3.0.0", - "rehype-parse": "^9.0.0", - "rehype-stringify": "^10.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", - "integrity": "sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-html": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype-parse/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype-raw/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", - "integrity": "sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype-stringify/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/remark-directive/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/remark-expressive-code/-/remark-expressive-code-0.30.1.tgz", - "integrity": "sha512-1cxsvXn1FyZsgaZXvkV+uoJLkg0rcS/k9Yemw211oD8Fblhh67Gb6ThxbuQdPf346kgg5D4R/iVyR49oAS5kbg==", - "dependencies": { - "expressive-code": "^0.30.1", - "hast-util-to-html": "^8.0.4", - "unist-util-visit": "^4.1.2" - } - }, - "node_modules/remark-expressive-code/node_modules/@types/hast": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", - "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-to-html": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", - "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^7.0.0", - "hast-util-whitespace": "^2.0.0", - "html-void-elements": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/remark-expressive-code/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/remark-expressive-code/node_modules/unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-expressive-code/node_modules/vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/remark-gfm/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", - "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/remark-parse/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", - "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/remark-rehype/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-smartypants": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", - "integrity": "sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==", - "dependencies": { - "retext": "^8.1.0", - "retext-smartypants": "^5.1.0", - "unist-util-visit": "^4.1.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/remark-stringify/node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/retext": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", - "integrity": "sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "retext-latin": "^3.0.0", - "retext-stringify": "^3.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-latin": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-3.1.0.tgz", - "integrity": "sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "parse-latin": "^5.0.0", - "unherit": "^3.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-smartypants": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", - "integrity": "sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-stringify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", - "integrity": "sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "optional": true, - "peer": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/server-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", - "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==" - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, - "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" - }, - "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shiki": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.2.1.tgz", - "integrity": "sha512-u+XW6o0vCkUNlneZb914dLO+AayEIwK5tI62WeS//R5HIXBFiYaj/Hc5xcq27Yh83Grr4JbNtUBV8W6zyK4hWg==", - "dependencies": { - "@shikijs/core": "1.2.1" - } - }, - "node_modules/shikiji": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.6.13.tgz", - "integrity": "sha512-4T7X39csvhT0p7GDnq9vysWddf2b6BeioiN3Ymhnt3xcy9tXmDcnsEFVxX18Z4YcQgEE/w48dLJ4pPPUcG9KkA==", - "dependencies": { - "hast-util-to-html": "^9.0.0" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/stdin-discarder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", - "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", - "dependencies": { - "bl": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/streamx": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", - "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", - "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^10.2.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svelte": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", - "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte-hmr": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", - "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, - "node_modules/svelte2tsx": { - "version": "0.6.27", - "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.6.27.tgz", - "integrity": "sha512-E1uPW1o6VsbRz+nUk3fznZ2lSmCITAJoNu8AYefWSvIwE2pSB01i5sId4RMbWNzfcwCQl1DcgGShCPcldl4rvg==", - "dependencies": { - "dedent-js": "^1.0.1", - "pascal-case": "^3.1.1" - }, - "peerDependencies": { - "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", - "typescript": "^4.9.4 || ^5.0.0" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/tar/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tsconfck": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.0.tgz", - "integrity": "sha512-w3wnsIrJNi7avf4Zb0VjOoodoO0woEqGgZGQm+LHH9przdUI+XDKsWAXwxHA1DaRTjeuZNcregSzr7RaA8zG9A==", - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "optional": true, - "peer": true - }, - "node_modules/unherit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz", - "integrity": "sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "dependencies": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-find-after/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-modify-children": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-3.1.1.tgz", - "integrity": "sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==", - "dependencies": { - "@types/unist": "^2.0.0", - "array-iterate": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-remove": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-4.0.0.tgz", - "integrity": "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-remove-position/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-remove/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-children": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", - "integrity": "sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/vfile-location/node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", - "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", - "optional": true, - "peer": true, - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "hasInstallScript": true, - "optional": true, - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/web-vitals": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-pm": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.1.1.tgz", - "integrity": "sha512-xzzxNw2wMaoCWXiGE8IJ9wuPMU+EYhFksjHxrRT8kMT5SnocBPRg69YAMtyV4D12fP582RA+k3P8H9J5EMdIxQ==", - "dependencies": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8.15" - } - }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/widest-line/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.22.5.tgz", - "integrity": "sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==", - "peerDependencies": { - "zod": "^3.22.4" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/docs/package.json b/docs/package.json index 520d3f94b..632118457 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,8 +7,10 @@ "start": "astro dev", "build": "astro build", "preview": "astro preview", - "astro": "astro" + "astro": "astro", + "preinstall": "npx only-allow pnpm" }, + "packageManager": "pnpm@10.23.0", "dependencies": { "@astrojs/starlight": "^0.15.1", "@astrojs/svelte": "^5.2.0", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 000000000..e21ab01ea --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,5522 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@astrojs/starlight': + specifier: ^0.15.1 + version: 0.15.4(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3)) + '@astrojs/svelte': + specifier: ^5.2.0 + version: 5.7.3(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))(svelte@4.2.20)(typescript@5.9.3)(vite@5.4.21) + '@astrojs/vercel': + specifier: ^7.5.0 + version: 7.8.2(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))(rollup@4.53.5)(svelte@4.2.20) + '@fontsource/ibm-plex-serif': + specifier: ^5.0.8 + version: 5.2.7 + astro: + specifier: ^4.0.0 + version: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + sharp: + specifier: ^0.32.5 + version: 0.32.6 + svelte: + specifier: ^4.2.12 + version: 4.2.20 + typescript: + specifier: ^5.4.3 + version: 5.9.3 + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@astrojs/compiler@2.13.0': + resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==} + + '@astrojs/internal-helpers@0.4.1': + resolution: {integrity: sha512-bMf9jFihO8YP940uD70SI/RDzIhUHJAolWVcO1v5PUivxGKvfLZTLTVVxEYzGYyPsA3ivdLNqMnL5VgmQySa+g==} + + '@astrojs/internal-helpers@0.4.2': + resolution: {integrity: sha512-EdDWkC3JJVcpGpqJAU/5hSk2LKXyG3mNGkzGoAuyK+xoPHbaVdSuIWoN1QTnmK3N/gGfaaAfM8gO2KDCAW7S3w==} + + '@astrojs/markdown-remark@5.1.0': + resolution: {integrity: sha512-S6Z3K2hOB7MfjeDoHsotnP/q2UsnEDB8NlNAaCjMDsGBZfTUbWxyLW3CaphEWw08f6KLZi2ibK9yC3BaMhh2NQ==} + + '@astrojs/markdown-remark@5.3.0': + resolution: {integrity: sha512-r0Ikqr0e6ozPb5bvhup1qdWnSPUvQu6tub4ZLYaKyG50BXZ0ej6FhGz3GpChKpH7kglRFPObJd/bDyf2VM9pkg==} + + '@astrojs/mdx@2.3.1': + resolution: {integrity: sha512-BOQFKD2Pi9cRntNQJlpF2fh4xV8doNpmVy9NKI95r4jsitrY4X5aTOhAowi+fkQgP/zW1A4HwCyQ6Pdam6z8zQ==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + peerDependencies: + astro: ^4.0.0 + + '@astrojs/prism@3.1.0': + resolution: {integrity: sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + + '@astrojs/prism@3.3.0': + resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@astrojs/sitemap@3.6.0': + resolution: {integrity: sha512-4aHkvcOZBWJigRmMIAJwRQXBS+ayoP5z40OklTXYXhUDhwusz+DyDl+nSshY6y9DvkVEavwNcFO8FD81iGhXjg==} + + '@astrojs/starlight@0.15.4': + resolution: {integrity: sha512-o3heYH+RltsCsvO3L0qLnnFJEakwLSRoxW4wFX2zDeDWta9BIpdSOo7+Zg+sSn7k9RPOhI9SGvdFx67B53I18Q==} + peerDependencies: + astro: ^4.0.0 + + '@astrojs/svelte@5.7.3': + resolution: {integrity: sha512-0PAwn2KLVpGsJppG8dWM1P9+/VrjAdhMWgEgwC1PjY2xFG565bTw7OuGaS5zh5Fu4AcjVoBkVQKjW/N3mLnrJA==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + peerDependencies: + astro: ^4.0.0 + svelte: ^4.0.0 || ^5.0.0-next.190 + typescript: ^5.3.3 + + '@astrojs/telemetry@3.1.0': + resolution: {integrity: sha512-/ca/+D8MIKEC8/A9cSaPUqQNZm+Es/ZinRv0ZAzvu2ios7POQSsVD+VOj7/hypWNsNM3T7RpfgNq7H2TU1KEHA==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + + '@astrojs/vercel@7.8.2': + resolution: {integrity: sha512-U2JsfN0LzFMX5CPrcb+5bAAyqyYURP6Dk/mUIXX87r5x4baQy+juU+ntvf926YA0tR7u6jPRXHymE2axQ/l3NQ==} + peerDependencies: + astro: ^4.2.0 + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@expressive-code/core@0.31.0': + resolution: {integrity: sha512-zeCuojWRYeFs0UDOhzpKMzpjI/tJPCQna4jcVp5SJLMn4qNtHXgVmz3AngoMFoFcAlK6meE3wxzy//0d6K4NPw==} + + '@expressive-code/plugin-frames@0.31.0': + resolution: {integrity: sha512-eYWfK3i4w2gSpOGBFNnu05JKSXC90APgUNdam8y5i0Ie2CVAwpxDtEp0NRqugvEKC0aMJe6ZmHN5Hu2WAVJmig==} + + '@expressive-code/plugin-shiki@0.31.0': + resolution: {integrity: sha512-fU5wPPfV1LGcS+Z1wcEkzI1fzBq9IAdt0DN0ni8sT7E+gpkULda4GA4IFD9iWKCGIhSDsBbG+bjc9hrYoJsDIQ==} + + '@expressive-code/plugin-text-markers@0.31.0': + resolution: {integrity: sha512-32o3pPMBq6bVUfRsAfFyqNpHbD1Z3iftoX9yt95F5zakLMsmHzZL4f0jyNr8XpXe7qcTnl0kIijBkUpvS6Pxfg==} + + '@fontsource/ibm-plex-serif@5.2.7': + resolution: {integrity: sha512-04owmc2OQQ/DAMjXjEMJc+7V4dBVmR01aIFOg4cuqS8pQ4HbvtlYs/u6+O0vCt21EMx5M/azIbgx43iKyisEOA==} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@mapbox/node-pre-gyp@2.0.3': + resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} + engines: {node: '>=18'} + hasBin: true + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + + '@pagefind/darwin-arm64@1.4.0': + resolution: {integrity: sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.4.0': + resolution: {integrity: sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==} + cpu: [x64] + os: [darwin] + + '@pagefind/default-ui@1.4.0': + resolution: {integrity: sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==} + + '@pagefind/freebsd-x64@1.4.0': + resolution: {integrity: sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==} + cpu: [x64] + os: [freebsd] + + '@pagefind/linux-arm64@1.4.0': + resolution: {integrity: sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.4.0': + resolution: {integrity: sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-x64@1.4.0': + resolution: {integrity: sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==} + cpu: [x64] + os: [win32] + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.53.5': + resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.5': + resolution: {integrity: sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.5': + resolution: {integrity: sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.5': + resolution: {integrity: sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.5': + resolution: {integrity: sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.5': + resolution: {integrity: sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + resolution: {integrity: sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + resolution: {integrity: sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.5': + resolution: {integrity: sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.5': + resolution: {integrity: sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.5': + resolution: {integrity: sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + resolution: {integrity: sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + resolution: {integrity: sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.5': + resolution: {integrity: sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.5': + resolution: {integrity: sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.5': + resolution: {integrity: sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.5': + resolution: {integrity: sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.5': + resolution: {integrity: sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + resolution: {integrity: sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.5': + resolution: {integrity: sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.5': + resolution: {integrity: sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.5': + resolution: {integrity: sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.29.2': + resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} + + '@shikijs/engine-javascript@1.29.2': + resolution: {integrity: sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==} + + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + + '@shikijs/langs@1.29.2': + resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==} + + '@shikijs/themes@1.29.2': + resolution: {integrity: sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==} + + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0': + resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@sveltejs/vite-plugin-svelte@3.1.2': + resolution: {integrity: sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@1.0.4': + resolution: {integrity: sha512-ABoYdNQ/kBSsLvZAekMhIPMQ3YUZvavStpKYs7BjLLuKVmIMA0LUgZ7b54zzuWJRbHF80v1cNf4r90Vd6eMQDg==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/parse5@6.0.3': + resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vercel/analytics@1.6.1': + resolution: {integrity: sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==} + peerDependencies: + '@remix-run/react': ^2 + '@sveltejs/kit': ^1 || ^2 + next: '>= 13' + react: ^18 || ^19 || ^19.0.0-rc + svelte: '>= 4' + vue: ^3 + vue-router: ^4 + peerDependenciesMeta: + '@remix-run/react': + optional: true + '@sveltejs/kit': + optional: true + next: + optional: true + react: + optional: true + svelte: + optional: true + vue: + optional: true + vue-router: + optional: true + + '@vercel/edge@1.2.2': + resolution: {integrity: sha512-1+y+f6rk0Yc9ss9bRDgz/gdpLimwoRteKHhrcgHvEpjbP1nyT3ByqEMWm2BTcpIO5UtDmIFXc8zdq4LR190PDA==} + + '@vercel/nft@0.27.10': + resolution: {integrity: sha512-zbaF9Wp/NsZtKLE4uVmL3FyfFwlpDyuymQM1kPbeT0mVOHKDQQNjnnfslB3REg3oZprmNFJuh3pkHBk2qAaizg==} + engines: {node: '>=16'} + hasBin: true + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + astro-expressive-code@0.31.0: + resolution: {integrity: sha512-o6eFrRSYLnlM/2FKkO3MgkbmVxT8N6DJcKvbRf1wbUcRXpz7s1KfugbdsaGw3ABEWUBuQIBsRppcGGw2L816Vg==} + peerDependencies: + astro: ^3.3.0 || ^4.0.0-beta + + astro@4.16.19: + resolution: {integrity: sha512-baeSswPC5ZYvhGDoj25L2FuzKRWMgx105FetOPQVJFMCAp0o08OonYC7AhwsFdhvp7GapqjnC1Fe3lKb2lupYw==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + b4a@1.7.3: + resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.5.2: + resolution: {integrity: sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-os@3.6.2: + resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-stream@2.7.0: + resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.3.2: + resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} + + base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.9.10: + resolution: {integrity: sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==} + hasBin: true + + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + bcp-47@2.1.0: + resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + caniuse-lite@1.0.30001760: + resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + code-red@1.0.4: + resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + css-selector-parser@3.3.0: + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + dedent-js@1.0.1: + resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + deterministic-object-hash@2.0.2: + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} + engines: {node: '>=18'} + + devalue@5.6.1: + resolution: {integrity: sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + expressive-code@0.31.0: + resolution: {integrity: sha512-rxKGYS8iRwNUbRNfyCyoe3XQvBLTtGdXbNKM+ODDWCn4VL2DVT1gD1M2N2Alg8HQHIWZJsZIMsYbziO0MRjPlw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@7.1.2: + resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@3.1.1: + resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@7.2.3: + resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@8.0.4: + resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@7.1.0: + resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@2.0.1: + resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@7.2.0: + resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} + + hastscript@8.0.0: + resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@2.0.1: + resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + + nlcst-to-string@3.1.1: + resolution: {integrity: sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-abi@3.85.0: + resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==} + engines: {node: '>=10'} + + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + oniguruma-to-es@2.3.0: + resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} + + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-queue@8.1.1: + resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==} + engines: {node: '>=18'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pagefind@1.4.0: + resolution: {integrity: sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==} + hasBin: true + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-latin@5.0.1: + resolution: {integrity: sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + hasBin: true + + preferred-pm@4.1.1: + resolution: {integrity: sha512-rU+ZAv1Ur9jAUZtGPebQVQPzdGhNzaEiQ7VL9+cjsAWPHFYOccNXPNiev1CCDSOg/2j7UujM7ojNhpkuILEVNQ==} + engines: {node: '>=18.12'} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regex-recursion@5.1.1: + resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.1.1: + resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-expressive-code@0.31.0: + resolution: {integrity: sha512-ZnKXo9lB0kBUHZIlw2NdqMMgXriVVajEhtQfJ+MWeibMpyM1kuOa28jefNfNFd3FAoNPrc/A3M0fDRkYvWw9Gw==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-smartypants@2.1.0: + resolution: {integrity: sha512-qoF6Vz3BjU2tP6OfZqHOvCU0ACmu/6jhGaINSQRI9mM7wCxNQTKB3JUAN4SVoN2ybElEDTxBIABRep7e569iJw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + retext-latin@3.1.0: + resolution: {integrity: sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@5.2.0: + resolution: {integrity: sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@3.1.0: + resolution: {integrity: sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@8.1.0: + resolution: {integrity: sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.53.5: + resolution: {integrity: sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} + engines: {node: '>=14.15.0'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shiki@1.29.2: + resolution: {integrity: sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==} + + shikiji@0.8.7: + resolution: {integrity: sha512-j5usxwI0yHkDTHOuhuSJl9+wT5CNYeYO82dJMSJBlJ/NYT5SIebGcPoL6y9QOyH15wGrJC4LOP2nz5k8mUDGRQ==} + deprecated: Deprecated, use shiki instead + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@8.0.2: + resolution: {integrity: sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==} + engines: {node: '>=14.0.0', npm: '>=6.0.0'} + hasBin: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + stream-replace-string@2.0.0: + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + svelte-hmr@0.16.0: + resolution: {integrity: sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: ^3.19.0 || ^4.0.0 + + svelte2tsx@0.7.45: + resolution: {integrity: sha512-cSci+mYGygYBHIZLHlm/jYlEc1acjAHqaQaDFHdEBpUueM9kSTnPpvPtSl5VkJOU1qSJ7h1K+6F/LIUYiqC8VA==} + peerDependencies: + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 + typescript: ^4.9.4 || ^5.0.0 + + svelte@4.2.20: + resolution: {integrity: sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q==} + engines: {node: '>=16'} + + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-fs@3.1.1: + resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + tar@7.5.2: + resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} + engines: {node: '>=18'} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unherit@3.0.1: + resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} + + unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-modify-children@3.1.1: + resolution: {integrity: sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@4.0.4: + resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-remove@4.0.0: + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} + + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@2.0.2: + resolution: {integrity: sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@4.1.2: + resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-location@4.1.0: + resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitefu@0.2.5: + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + vite: + optional: true + + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + web-vitals@3.5.2: + resolution: {integrity: sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + + which-pm@3.0.1: + resolution: {integrity: sha512-v2JrMq0waAI4ju1xU5x3blsxBBMgdgZve580iYMN5frDaLGjbA24fok7wKCsya8KLVO19Ju4XDc5+zTZCJkQfg==} + engines: {node: '>=18.12'} + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zod-to-json-schema@3.25.0: + resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} + peerDependencies: + zod: ^3.25 || ^4 + + zod-to-ts@1.2.0: + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} + peerDependencies: + typescript: ^4.9.4 || ^5.0.2 + zod: ^3 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@astrojs/compiler@2.13.0': {} + + '@astrojs/internal-helpers@0.4.1': {} + + '@astrojs/internal-helpers@0.4.2': {} + + '@astrojs/markdown-remark@5.1.0': + dependencies: + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 2.1.0 + shiki: 1.29.2 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/markdown-remark@5.3.0': + dependencies: + '@astrojs/prism': 3.1.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 1.29.2 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/mdx@2.3.1(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))': + dependencies: + '@astrojs/markdown-remark': 5.1.0 + '@mdx-js/mdx': 3.1.1 + acorn: 8.15.0 + astro: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + es-module-lexer: 1.7.0 + estree-util-visit: 2.0.0 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + hast-util-to-html: 9.0.5 + kleur: 4.1.5 + rehype-raw: 7.0.0 + remark-gfm: 4.0.1 + remark-smartypants: 2.1.0 + source-map: 0.7.6 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@3.1.0': + dependencies: + prismjs: 1.30.0 + + '@astrojs/prism@3.3.0': + dependencies: + prismjs: 1.30.0 + + '@astrojs/sitemap@3.6.0': + dependencies: + sitemap: 8.0.2 + stream-replace-string: 2.0.0 + zod: 3.25.76 + + '@astrojs/starlight@0.15.4(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))': + dependencies: + '@astrojs/mdx': 2.3.1(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3)) + '@astrojs/sitemap': 3.6.0 + '@pagefind/default-ui': 1.4.0 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + astro: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + astro-expressive-code: 0.31.0(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3)) + bcp-47: 2.1.0 + hast-util-select: 6.0.4 + hastscript: 8.0.0 + mdast-util-directive: 3.1.0 + pagefind: 1.4.0 + rehype: 13.0.2 + remark-directive: 3.0.1 + unified: 11.0.5 + unist-util-remove: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/svelte@5.7.3(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))(svelte@4.2.20)(typescript@5.9.3)(vite@5.4.21)': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@5.4.21) + astro: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + svelte: 4.2.20 + svelte2tsx: 0.7.45(svelte@4.2.20)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + - vite + + '@astrojs/telemetry@3.1.0': + dependencies: + ci-info: 4.3.1 + debug: 4.4.3 + dlv: 1.1.3 + dset: 3.1.4 + is-docker: 3.0.0 + is-wsl: 3.1.0 + which-pm-runs: 1.1.0 + transitivePeerDependencies: + - supports-color + + '@astrojs/vercel@7.8.2(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3))(rollup@4.53.5)(svelte@4.2.20)': + dependencies: + '@astrojs/internal-helpers': 0.4.2 + '@vercel/analytics': 1.6.1(svelte@4.2.20) + '@vercel/edge': 1.2.2 + '@vercel/nft': 0.27.10(rollup@4.53.5) + astro: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + esbuild: 0.21.5 + fast-glob: 3.3.3 + web-vitals: 3.5.2 + transitivePeerDependencies: + - '@remix-run/react' + - '@sveltejs/kit' + - encoding + - next + - react + - rollup + - supports-color + - svelte + - vue + - vue-router + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@ctrl/tinycolor@3.6.1': {} + + '@emnapi/runtime@1.7.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@expressive-code/core@0.31.0': + dependencies: + '@ctrl/tinycolor': 3.6.1 + hast-util-to-html: 8.0.4 + hastscript: 7.2.0 + postcss: 8.5.6 + postcss-nested: 6.2.0(postcss@8.5.6) + + '@expressive-code/plugin-frames@0.31.0': + dependencies: + '@expressive-code/core': 0.31.0 + hastscript: 7.2.0 + + '@expressive-code/plugin-shiki@0.31.0': + dependencies: + '@expressive-code/core': 0.31.0 + shikiji: 0.8.7 + + '@expressive-code/plugin-text-markers@0.31.0': + dependencies: + '@expressive-code/core': 0.31.0 + hastscript: 7.2.0 + unist-util-visit-parents: 5.1.3 + + '@fontsource/ibm-plex-serif@5.2.7': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.7.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mapbox/node-pre-gyp@2.0.3': + dependencies: + consola: 3.4.2 + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6 + node-fetch: 2.7.0 + nopt: 8.1.0 + semver: 7.7.3 + tar: 7.5.2 + transitivePeerDependencies: + - encoding + - supports-color + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@oslojs/encoding@1.1.0': {} + + '@pagefind/darwin-arm64@1.4.0': + optional: true + + '@pagefind/darwin-x64@1.4.0': + optional: true + + '@pagefind/default-ui@1.4.0': {} + + '@pagefind/freebsd-x64@1.4.0': + optional: true + + '@pagefind/linux-arm64@1.4.0': + optional: true + + '@pagefind/linux-x64@1.4.0': + optional: true + + '@pagefind/windows-x64@1.4.0': + optional: true + + '@rollup/pluginutils@5.3.0(rollup@4.53.5)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.53.5 + + '@rollup/rollup-android-arm-eabi@4.53.5': + optional: true + + '@rollup/rollup-android-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-x64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.5': + optional: true + + '@shikijs/core@1.29.2': + dependencies: + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 2.3.0 + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/themes@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21))(svelte@4.2.20)(vite@5.4.21)': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.20)(vite@5.4.21) + debug: 4.4.3 + svelte: 4.2.20 + vite: 5.4.21 + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21)': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.20)(vite@5.4.21))(svelte@4.2.20)(vite@5.4.21) + debug: 4.4.3 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.21 + svelte: 4.2.20 + svelte-hmr: 0.16.0(svelte@4.2.20) + vite: 5.4.21 + vitefu: 0.2.5(vite@5.4.21) + transitivePeerDependencies: + - supports-color + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/cookie@0.6.0': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/nlcst@1.0.4': + dependencies: + '@types/unist': 2.0.11 + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + + '@types/node@17.0.45': {} + + '@types/parse5@6.0.3': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 17.0.45 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.0': {} + + '@vercel/analytics@1.6.1(svelte@4.2.20)': + optionalDependencies: + svelte: 4.2.20 + + '@vercel/edge@1.2.2': {} + + '@vercel/nft@0.27.10(rollup@4.53.5)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.3 + '@rollup/pluginutils': 5.3.0(rollup@4.53.5) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.3 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + abbrev@3.0.1: {} + + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + agent-base@7.1.4: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@6.2.3: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-iterate@2.0.1: {} + + astring@1.9.0: {} + + astro-expressive-code@0.31.0(astro@4.16.19(rollup@4.53.5)(typescript@5.9.3)): + dependencies: + astro: 4.16.19(rollup@4.53.5)(typescript@5.9.3) + remark-expressive-code: 0.31.0 + + astro@4.16.19(rollup@4.53.5)(typescript@5.9.3): + dependencies: + '@astrojs/compiler': 2.13.0 + '@astrojs/internal-helpers': 0.4.1 + '@astrojs/markdown-remark': 5.3.0 + '@astrojs/telemetry': 3.1.0 + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.53.5) + '@types/babel__core': 7.20.5 + '@types/cookie': 0.6.0 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.3.1 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 0.7.2 + cssesc: 3.0.0 + debug: 4.4.3 + deterministic-object-hash: 2.0.2 + devalue: 5.6.1 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.7.0 + esbuild: 0.21.5 + estree-walker: 3.0.3 + fast-glob: 3.3.3 + flattie: 1.1.1 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + js-yaml: 4.1.1 + kleur: 4.1.5 + magic-string: 0.30.21 + magicast: 0.3.5 + micromatch: 4.0.8 + mrmime: 2.0.1 + neotraverse: 0.6.18 + ora: 8.2.0 + p-limit: 6.2.0 + p-queue: 8.1.1 + preferred-pm: 4.1.1 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.3 + shiki: 1.29.2 + tinyexec: 0.3.2 + tsconfck: 3.1.6(typescript@5.9.3) + unist-util-visit: 5.0.0 + vfile: 6.0.3 + vite: 5.4.21 + vitefu: 1.1.1(vite@5.4.21) + which-pm: 3.0.1 + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + zod: 3.25.76 + zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) + optionalDependencies: + sharp: 0.33.5 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - typescript + + async-sema@3.1.1: {} + + axobject-query@4.1.0: {} + + b4a@1.7.3: {} + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + bare-events@2.8.2: {} + + bare-fs@4.5.2: + dependencies: + bare-events: 2.8.2 + bare-path: 3.0.0 + bare-stream: 2.7.0(bare-events@2.8.2) + bare-url: 2.3.2 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + optional: true + + bare-os@3.6.2: + optional: true + + bare-path@3.0.0: + dependencies: + bare-os: 3.6.2 + optional: true + + bare-stream@2.7.0(bare-events@2.8.2): + dependencies: + streamx: 2.23.0 + optionalDependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + optional: true + + bare-url@2.3.2: + dependencies: + bare-path: 3.0.0 + optional: true + + base-64@1.0.0: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.9.10: {} + + bcp-47-match@2.0.3: {} + + bcp-47@2.1.0: + dependencies: + is-alphabetical: 2.0.1 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + boolbase@1.0.0: {} + + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.2 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.10 + caniuse-lite: 1.0.30001760 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + camelcase@8.0.0: {} + + caniuse-lite@1.0.30001760: {} + + ccount@2.0.1: {} + + chalk@5.6.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chownr@1.1.4: {} + + chownr@3.0.0: {} + + ci-info@4.3.1: {} + + cli-boxes@3.0.0: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} + + clsx@2.1.1: {} + + code-red@1.0.4: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@types/estree': 1.0.8 + acorn: 8.15.0 + estree-walker: 3.0.3 + periscopic: 3.1.0 + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + comma-separated-tokens@2.0.3: {} + + common-ancestor-path@1.0.1: {} + + concat-map@0.0.1: {} + + consola@3.4.2: {} + + convert-source-map@2.0.0: {} + + cookie@0.7.2: {} + + css-selector-parser@3.3.0: {} + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + cssesc@3.0.0: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + dedent-js@1.0.1: {} + + deep-extend@0.6.0: {} + + deepmerge@4.3.1: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + deterministic-object-hash@2.0.2: + dependencies: + base-64: 1.0.0 + + devalue@5.6.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@5.2.0: {} + + direction@2.0.1: {} + + dlv@1.1.3: {} + + dset@3.1.4: {} + + electron-to-chromium@1.5.267: {} + + emoji-regex-xs@1.0.0: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + entities@6.0.1: {} + + es-module-lexer@1.7.0: {} + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-string-regexp@5.0.0: {} + + esprima@4.0.1: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + eventemitter3@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + + expand-template@2.0.3: {} + + expressive-code@0.31.0: + dependencies: + '@expressive-code/core': 0.31.0 + '@expressive-code/plugin-frames': 0.31.0 + '@expressive-code/plugin-shiki': 0.31.0 + '@expressive-code/plugin-text-markers': 0.31.0 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.1: {} + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-yarn-workspace-root2@1.2.16: + dependencies: + micromatch: 4.0.8 + pkg-dir: 4.2.0 + + flattie@1.1.1: {} + + fs-constants@1.0.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + get-east-asian-width@1.4.0: {} + + github-from-package@0.0.0: {} + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@7.1.2: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + hastscript: 7.2.0 + property-information: 6.5.0 + vfile: 5.3.7 + vfile-location: 4.1.0 + web-namespaces: 2.0.1 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@3.1.1: + dependencies: + '@types/hast': 2.3.10 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@7.2.3: + dependencies: + '@types/hast': 2.3.10 + '@types/parse5': 6.0.3 + hast-util-from-parse5: 7.1.2 + hast-util-to-parse5: 7.1.0 + html-void-elements: 2.0.1 + parse5: 6.0.1 + unist-util-position: 4.0.4 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.3.0 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@8.0.4: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-raw: 7.2.3 + hast-util-whitespace: 2.0.1 + html-void-elements: 2.0.1 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@7.1.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 2.0.3 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@2.0.1: {} + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@7.2.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 3.1.1 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + + hastscript@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + html-escaper@3.0.3: {} + + html-void-elements@2.0.1: {} + + html-void-elements@3.0.0: {} + + http-cache-semantics@4.2.0: {} + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ieee754@1.2.1: {} + + import-meta-resolve@4.2.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + inline-style-parser@0.2.7: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.3.4: {} + + is-buffer@2.0.5: {} + + is-decimal@2.0.1: {} + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json5@2.2.3: {} + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + load-yaml-file@0.2.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + locate-character@3.0.0: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 + + longest-streak@3.1.0: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.30: {} + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mimic-function@5.0.1: {} + + mimic-response@3.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + + mkdirp-classic@0.5.3: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + napi-build-utils@2.0.0: {} + + neotraverse@0.6.18: {} + + nlcst-to-string@3.1.1: + dependencies: + '@types/nlcst': 1.0.4 + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-abi@3.85.0: + dependencies: + semver: 7.7.3 + + node-addon-api@6.1.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build@4.8.4: {} + + node-releases@2.0.27: {} + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + oniguruma-to-es@2.3.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.1.1 + regex-recursion: 5.1.1 + + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@6.2.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-queue@8.1.1: + dependencies: + eventemitter3: 5.0.1 + p-timeout: 6.1.4 + + p-timeout@6.1.4: {} + + p-try@2.2.0: {} + + pagefind@1.4.0: + optionalDependencies: + '@pagefind/darwin-arm64': 1.4.0 + '@pagefind/darwin-x64': 1.4.0 + '@pagefind/freebsd-x64': 1.4.0 + '@pagefind/linux-arm64': 1.4.0 + '@pagefind/linux-x64': 1.4.0 + '@pagefind/windows-x64': 1.4.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-latin@5.0.1: + dependencies: + nlcst-to-string: 3.1.1 + unist-util-modify-children: 3.1.1 + unist-util-visit-children: 2.0.2 + + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@6.0.1: {} + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + periscopic@3.1.0: + dependencies: + '@types/estree': 1.0.8 + estree-walker: 3.0.3 + is-reference: 3.0.3 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@4.0.1: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.85.0 + pump: 3.0.3 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + + preferred-pm@4.1.1: + dependencies: + find-up-simple: 1.0.1 + find-yarn-workspace-root2: 1.2.16 + which-pm: 3.0.1 + + prismjs@1.30.0: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + property-information@6.5.0: {} + + property-information@7.1.0: {} + + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + queue-microtask@1.2.3: {} + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regex-recursion@5.1.1: + dependencies: + regex: 5.1.1 + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.1.1: + dependencies: + regex-utilities: 2.3.0 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-expressive-code@0.31.0: + dependencies: + expressive-code: 0.31.0 + hast-util-to-html: 8.0.4 + unist-util-visit: 4.1.2 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-smartypants@2.1.0: + dependencies: + retext: 8.1.0 + retext-smartypants: 5.2.0 + unist-util-visit: 5.0.0 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + resolve-from@5.0.0: {} + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + retext-latin@3.1.0: + dependencies: + '@types/nlcst': 1.0.4 + parse-latin: 5.0.1 + unherit: 3.0.1 + unified: 10.1.2 + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@5.2.0: + dependencies: + '@types/nlcst': 1.0.4 + nlcst-to-string: 3.1.1 + unified: 10.1.2 + unist-util-visit: 4.1.2 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.0.0 + + retext-stringify@3.1.0: + dependencies: + '@types/nlcst': 1.0.4 + nlcst-to-string: 3.1.1 + unified: 10.1.2 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@8.1.0: + dependencies: + '@types/nlcst': 1.0.4 + retext-latin: 3.1.0 + retext-stringify: 3.1.0 + unified: 10.1.2 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + + reusify@1.1.0: {} + + rollup@4.53.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.5 + '@rollup/rollup-android-arm64': 4.53.5 + '@rollup/rollup-darwin-arm64': 4.53.5 + '@rollup/rollup-darwin-x64': 4.53.5 + '@rollup/rollup-freebsd-arm64': 4.53.5 + '@rollup/rollup-freebsd-x64': 4.53.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.5 + '@rollup/rollup-linux-arm-musleabihf': 4.53.5 + '@rollup/rollup-linux-arm64-gnu': 4.53.5 + '@rollup/rollup-linux-arm64-musl': 4.53.5 + '@rollup/rollup-linux-loong64-gnu': 4.53.5 + '@rollup/rollup-linux-ppc64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-musl': 4.53.5 + '@rollup/rollup-linux-s390x-gnu': 4.53.5 + '@rollup/rollup-linux-x64-gnu': 4.53.5 + '@rollup/rollup-linux-x64-musl': 4.53.5 + '@rollup/rollup-openharmony-arm64': 4.53.5 + '@rollup/rollup-win32-arm64-msvc': 4.53.5 + '@rollup/rollup-win32-ia32-msvc': 4.53.5 + '@rollup/rollup-win32-x64-gnu': 4.53.5 + '@rollup/rollup-win32-x64-msvc': 4.53.5 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + sax@1.4.3: {} + + scule@1.3.0: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@6.3.1: {} + + semver@7.7.3: {} + + sharp@0.32.6: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + node-addon-api: 6.1.0 + prebuild-install: 7.1.3 + semver: 7.7.3 + simple-get: 4.0.1 + tar-fs: 3.1.1 + tunnel-agent: 0.6.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + + shiki@1.29.2: + dependencies: + '@shikijs/core': 1.29.2 + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/langs': 1.29.2 + '@shikijs/themes': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + shikiji@0.8.7: + dependencies: + hast-util-to-html: 9.0.5 + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + sisteransi@1.0.5: {} + + sitemap@8.0.2: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.4.3 + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + sprintf-js@1.0.3: {} + + stdin-discarder@0.2.2: {} + + stream-replace-string@2.0.0: {} + + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-bom@3.0.0: {} + + strip-json-comments@2.0.1: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + svelte-hmr@0.16.0(svelte@4.2.20): + dependencies: + svelte: 4.2.20 + + svelte2tsx@0.7.45(svelte@4.2.20)(typescript@5.9.3): + dependencies: + dedent-js: 1.0.1 + scule: 1.3.0 + svelte: 4.2.20 + typescript: 5.9.3 + + svelte@4.2.20: + dependencies: + '@ampproject/remapping': 2.3.0 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + code-red: 1.0.4 + css-tree: 2.3.1 + estree-walker: 3.0.3 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + periscopic: 3.1.0 + + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + tar-stream: 2.2.0 + + tar-fs@3.1.1: + dependencies: + pump: 3.0.3 + tar-stream: 3.1.7 + optionalDependencies: + bare-fs: 4.5.2 + bare-path: 3.0.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar-stream@3.1.7: + dependencies: + b4a: 1.7.3 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + tar@7.5.2: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + + text-decoder@1.2.3: + dependencies: + b4a: 1.7.3 + transitivePeerDependencies: + - react-native-b4a + + tinyexec@0.3.2: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tsconfck@3.1.6(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + tslib@2.8.1: + optional: true + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + type-fest@4.41.0: {} + + typescript@5.9.3: {} + + unherit@3.0.1: {} + + unified@10.1.2: + dependencies: + '@types/unist': 2.0.11 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 5.3.7 + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@5.2.1: + dependencies: + '@types/unist': 2.0.11 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@3.1.1: + dependencies: + '@types/unist': 2.0.11 + array-iterate: 2.0.1 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@4.0.4: + dependencies: + '@types/unist': 2.0.11 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + unist-util-remove@4.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unist-util-stringify-position@3.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@2.0.2: + dependencies: + '@types/unist': 2.0.11 + + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@5.1.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@4.1.2: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: {} + + vfile-location@4.1.0: + dependencies: + '@types/unist': 2.0.11 + vfile: 5.3.7 + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@3.1.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 3.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@5.3.7: + dependencies: + '@types/unist': 2.0.11 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@5.4.21: + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.53.5 + optionalDependencies: + fsevents: 2.3.3 + + vitefu@0.2.5(vite@5.4.21): + optionalDependencies: + vite: 5.4.21 + + vitefu@1.1.1(vite@5.4.21): + optionalDependencies: + vite: 5.4.21 + + web-namespaces@2.0.1: {} + + web-vitals@3.5.2: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-pm-runs@1.1.0: {} + + which-pm@3.0.1: + dependencies: + load-yaml-file: 0.2.0 + + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + xxhash-wasm@1.1.0: {} + + yallist@3.1.1: {} + + yallist@5.0.0: {} + + yargs-parser@21.1.1: {} + + yocto-queue@1.2.2: {} + + zod-to-json-schema@3.25.0(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-to-ts@1.2.0(typescript@5.9.3)(zod@3.25.76): + dependencies: + typescript: 5.9.3 + zod: 3.25.76 + + zod@3.25.76: {} + + zwitch@2.0.4: {} diff --git a/docs/pnpm-workspace.yaml b/docs/pnpm-workspace.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/docs/src/assets/codespaces.png b/docs/src/assets/codespaces.png new file mode 100644 index 000000000..2b8e8a43c Binary files /dev/null and b/docs/src/assets/codespaces.png differ diff --git a/docs/src/assets/rxjs/49/prototype.gif b/docs/src/assets/rxjs/49/prototype.gif new file mode 100644 index 000000000..32c33528c Binary files /dev/null and b/docs/src/assets/rxjs/49/prototype.gif differ diff --git a/docs/src/components/Author.astro b/docs/src/components/Author.astro index 3ac6d1b0c..43b3af29c 100644 --- a/docs/src/components/Author.astro +++ b/docs/src/components/Author.astro @@ -6,10 +6,11 @@ interface Props { twitter?: string; linkedin?: string; github?: string; + youtube?: string; labels?: Record; } -const { name, twitter, linkedin, github, data } = Astro.props; +const { name, twitter, linkedin, github, youtube, data } = Astro.props; ---

    @@ -23,6 +24,9 @@ const { name, twitter, linkedin, github, data } = Astro.props; {github && } + {youtube && + + }

    diff --git a/docs/src/components/ChallengeFooter.astro b/docs/src/components/ChallengeFooter.astro index 6a714b0d8..ccd4f1a83 100644 --- a/docs/src/components/ChallengeFooter.astro +++ b/docs/src/components/ChallengeFooter.astro @@ -5,7 +5,7 @@ import { getEntry } from 'astro:content'; import AnsweredUser from './github/AnsweredUser.svelte'; const { lang } = Astro.props; -const { author, challengeNumber, title, blogLink, videoLink, command } = Astro.props.entry.data; +const { author, challengeNumber, title, blogLink, videoLinks, command } = Astro.props.entry.data; const { data } = await getEntry('i18n', lang); const authorLink = `https://github.com/tomalaforge/angular-challenges/pulls?q=label%3A${challengeNumber}+label%3A"answer+author"`; @@ -70,8 +70,9 @@ const npxCommand = `npx nx serve ${command}`; {data['challenge.footer.blogPost']} } - {videoLink && - } + {videoLinks && videoLinks.map((videoLink) => ( + + ))}
    diff --git a/docs/src/components/CommentSection.astro b/docs/src/components/CommentSection.astro index b8563ae9d..778eba0a2 100644 --- a/docs/src/components/CommentSection.astro +++ b/docs/src/components/CommentSection.astro @@ -3,7 +3,8 @@ import type { Props } from '@astrojs/starlight/props'; const {lang, locale} = Astro.props; -const shortLang = lang.split('-')[0]; +// Chinese needs to `zh-CN` +// const shortLang =lang.split('-')[0]; ---
    @@ -19,7 +20,7 @@ const shortLang = lang.split('-')[0]; data-emit-metadata="0" data-input-position="bottom" data-theme="preferred_color_scheme" - data-lang={shortLang} + data-lang={lang} data-loading="lazy" crossorigin="anonymous" async> diff --git a/docs/src/components/Hero.astro b/docs/src/components/Hero.astro index 53d43a41c..8d9500eaa 100644 --- a/docs/src/components/Hero.astro +++ b/docs/src/components/Hero.astro @@ -2,9 +2,9 @@ import Default from '@astrojs/starlight/components/Hero.astro'; import MyIcon from './MyIcon.astro'; import { getEntry } from 'astro:content'; +import SponsorUser from './github/SponsorUser.svelte'; + -const sponsorFetch = await fetch('https://ghs.vercel.app/v2/sponsors/tomalaforge'); -const { sponsors } = await sponsorFetch.json(); const { lang } = Astro.props; const { data } = await getEntry('i18n', lang); @@ -12,22 +12,11 @@ const { data } = await getEntry('i18n', lang); @@ -57,14 +46,6 @@ const { data } = await getEntry('i18n', lang); display: inline-block; } - .avatar { - border-radius: 50%; - width: 30px; - height: auto; - vertical-align: middle; - margin-right: 0.5rem; - } - .action-button { display: flex !important; justify-content: center; diff --git a/docs/src/components/VideoButton.astro b/docs/src/components/VideoButton.astro index a739090b5..723ef30e9 100644 --- a/docs/src/components/VideoButton.astro +++ b/docs/src/components/VideoButton.astro @@ -5,12 +5,13 @@ interface Props { lang: any; link: string; alt: string; - flag?: 'FR'; + flag?: 'FR' | 'ES'; } const { link, alt, flag, lang } = Astro.props; const { data } = await getEntry('i18n', lang); const isFR = flag === 'FR'; +const isES = flag === 'ES'; --- {data['challenge.footer.video']} - {isFR && 🇫🇷} + {isFR && 🇫🇷} + {isES && 🇪🇸} diff --git a/docs/src/components/github/GitHubStats.svelte b/docs/src/components/github/GitHubStats.svelte index 2828fea11..8286a2894 100644 --- a/docs/src/components/github/GitHubStats.svelte +++ b/docs/src/components/github/GitHubStats.svelte @@ -84,6 +84,9 @@ const data = await refresh.json(); token.set(data.token); return; + } else { + token.set('delete'); + throw new Error('Failed to refresh token'); } } else { throw new Error('Failed to fetch data'); diff --git a/docs/src/components/github/SignUp.svelte b/docs/src/components/github/SignUp.svelte index 88f1bbac5..a98a2a943 100644 --- a/docs/src/components/github/SignUp.svelte +++ b/docs/src/components/github/SignUp.svelte @@ -53,6 +53,11 @@ background-color: #218838; } + a :global(svg) { + --sl-icon-color: initial; + } + + @media (width < 450px) { .github-sign-in { display: none; diff --git a/docs/src/components/github/SponsorUser.svelte b/docs/src/components/github/SponsorUser.svelte new file mode 100644 index 000000000..cc29003d7 --- /dev/null +++ b/docs/src/components/github/SponsorUser.svelte @@ -0,0 +1,40 @@ + + +{#each sponsors as { username, avatar }} + + {username} + +{/each} + + diff --git a/docs/src/components/github/github-store.ts b/docs/src/components/github/github-store.ts index 445bd6c3b..48c4ddee4 100644 --- a/docs/src/components/github/github-store.ts +++ b/docs/src/components/github/github-store.ts @@ -31,6 +31,7 @@ token.subscribe((value) => { if (value) { if (value === 'delete') { localStorage.removeItem(TOKEN_KEY); + token.set(null); return; } localStorage.setItem(TOKEN_KEY, JSON.stringify(value)); diff --git a/docs/src/components/leaderboard/LeaderboardAnswer.svelte b/docs/src/components/leaderboard/LeaderboardAnswer.svelte index 4a6872131..bfd43c935 100644 --- a/docs/src/components/leaderboard/LeaderboardAnswer.svelte +++ b/docs/src/components/leaderboard/LeaderboardAnswer.svelte @@ -7,6 +7,7 @@ let loading = true; let error = null; let isUsernamePresent = false; + let globalCount = 0; token.subscribe(token => { if (token) { @@ -34,16 +35,23 @@ break; } + globalCount = globalCount + items.length; + items.forEach(pr => { const userLogin = pr.user.login; + // Extract challenge number from labels + const challengeNumbers = pr.labels.filter(l => !isNaN(Number(l.name))).map(l => Number(l.name)); + const challengeNumber = challengeNumbers?.[0]; + if (!challengeNumber) return; // skip if no challenge number if (prCounts[userLogin]) { - prCounts[userLogin].count++; - prCounts[userLogin].challengeNumber.push(pr.labels.filter(l => !isNaN(Number(l.name))).map(l => Number(l.name))?.[0]); + // Only add if not already present + if (!prCounts[userLogin].challengeNumber.includes(challengeNumber)) { + prCounts[userLogin].challengeNumber.push(challengeNumber); + } } else { prCounts[userLogin] = { avatar: pr.user.avatar_url, - count: 1, - challengeNumber: [pr.labels.filter(l => !isNaN(Number(l.name))).map(l => Number(l.name))?.[0]] + challengeNumber: [challengeNumber] }; } }); @@ -60,9 +68,9 @@ users = Object.entries(prCounts).map(([login, pr]) => ({ login, avatar: pr.avatar, - count: pr.count, + count: pr.challengeNumber.length, // count unique challenges only challengeNumber: pr.challengeNumber.sort((a, b) => a - b), - })).filter((r) => r.login !== 'allcontributors[bot]').sort((a, b) => b.count - a.count); + })).filter((r) => r.login !== 'allcontributors[bot]' && r.login !== 'tomalaforge').sort((a, b) => b.count - a.count); } catch (e) { error = e.message; @@ -76,6 +84,7 @@ {#if !$isConnected}
    Log in to Github to see the list
    {:else} +🔥Total Answers: { globalCount } {#if isUsernamePresent}